Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > three times copy ctor called, one ctor called, why?

Reply
Thread Tools

three times copy ctor called, one ctor called, why?

 
 
Apricot
Guest
Posts: n/a
 
      04-15-2004
#include <iostream>
#include <string>
#include <map>
using namespace std ;
class tst
{
public :
tst() { cout << "tst::constructor" << endl ; }
tst(const tst & that) { cout << "tst::copy constructor" << endl ;
}
tst & operator =( const tst & that ) { cout << "tst:perator ="
<< endl ; }

~tst() { cout << "tst::destructor" << endl ; }
} ;
int main()
{
map < string , tst > a ;
tst e ;
a.insert(pair < string , tst > ("standard",e) ) ;

system("pause") ;
return 0 ;
}
///// Output ////////////
tst::constructor
tst::copy constructor
tst::copy constructor
tst::copy constructor
tst::destructor
tst::destructor
 
Reply With Quote
 
 
 
 
Kevin Goodsell
Guest
Posts: n/a
 
      04-15-2004
Apricot wrote:

> #include <iostream>
> #include <string>
> #include <map>
> using namespace std ;
> class tst
> {
> public :
> tst() { cout << "tst::constructor" << endl ; }
> tst(const tst & that) { cout << "tst::copy constructor" << endl ;
> }
> tst & operator =( const tst & that ) { cout << "tst:perator ="
> << endl ; }


Why have you not returned anything from this function?

>
> ~tst() { cout << "tst::destructor" << endl ; }
> } ;
> int main()
> {
> map < string , tst > a ;
> tst e ;
> a.insert(pair < string , tst > ("standard",e) ) ;


Actually, that should be 'const string'. I think it should be OK this
way, but I seem to recall some implementations having trouble inserting
into a map this way, or by using make_pair. For that reason, using
map<>::value_type (which you can be sure has exactly the right type) may
be preferable. I'd probably do this:

typedef map<string, tst> MapType;
MapType a;
tst e;
a.insert(MapType::value_type("standard", e));

>
> system("pause") ;
> return 0 ;
> }
> ///// Output ////////////
> tst::constructor
> tst::copy constructor
> tst::copy constructor
> tst::copy constructor
> tst::destructor
> tst::destructor


I don't see these results. What I do see might shed some light, however:

tst::constructor
tst::copy constructor
tst::copy constructor
tst::copy constructor
tst::destructor
tst::destructor
pause: not found
tst::destructor
tst::destructor

Notice that the ill-fated "pause" command came before two of the
destructor calls. Perhaps your pausing is preventing you from seeing
some of the destructor calls. If not that, then I suspect your compiler
is broken and due for an update.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
 
Reply With Quote
 
 
 
 
Amit Manocha
Guest
Posts: n/a
 
      04-15-2004
You are expecting a single copy ctor, because e is passed to a.insert.
but it should be called one more time - ("standard", e) to pair <T1,
T2> conversion. now why it is being called third time probably is due
to internal pair implementation (object is copied somewhere in temp
object) ?

Amit Manocha

Apricot <> wrote in message news:<>. ..
> #include <iostream>
> #include <string>
> #include <map>
> using namespace std ;
> class tst
> {
> public :
> tst() { cout << "tst::constructor" << endl ; }
> tst(const tst & that) { cout << "tst::copy constructor" << endl ;
> }
> tst & operator =( const tst & that ) { cout << "tst:perator ="
> << endl ; }
>
> ~tst() { cout << "tst::destructor" << endl ; }
> } ;
> int main()
> {
> map < string , tst > a ;
> tst e ;
> a.insert(pair < string , tst > ("standard",e) ) ;
>
> system("pause") ;
> return 0 ;
> }
> ///// Output ////////////
> tst::constructor
> tst::copy constructor
> tst::copy constructor
> tst::copy constructor
> tst::destructor
> tst::destructor

 
Reply With Quote
 
Michiel Salters
Guest
Posts: n/a
 
      04-15-2004
Kevin Goodsell <> wrote in message news:<TWqfc.11306$ hlink.net>...
> Apricot wrote:
>
> > #include <iostream>
> > #include <string>
> > #include <map>
> > using namespace std ;
> > class tst
> > {
> > public :
> > tst() { cout << "tst::constructor" << endl ; }
> > tst(const tst & that) { cout << "tst::copy constructor" << endl ;
> > }
> > tst & operator =( const tst & that ) { cout << "tst:perator ="
> > << endl ; }
> >
> > ~tst() { cout << "tst::destructor" << endl ; }
> > } ;
> > int main()
> > {
> > map < string , tst > a ;
> > tst e ;
> > a.insert(pair < string , tst > ("standard",e) ) ;
> >
> > system("pause") ;
> > return 0 ;
> > }
> > ///// Output ////////////
> > tst::constructor
> > tst::copy constructor
> > tst::copy constructor
> > tst::copy constructor
> > tst::destructor
> > tst::destructor

>
> I don't see these results. What I do see might shed some light, however:
>
> tst::constructor
> tst::copy constructor
> tst::copy constructor
> tst::copy constructor
> tst::destructor
> tst::destructor
> pause: not found
> tst::destructor
> tst::destructor
>
> Notice that the ill-fated "pause" command came before two of the
> destructor calls. Perhaps your pausing is preventing you from seeing
> some of the destructor calls. If not that, then I suspect your compiler
> is broken and due for an update.


Sorry for the long quote, but isn't this obvious? e is destroyed after
the pause, and the single tst in a is also destroyed later.

Regards,
Michiel Salters
 
Reply With Quote
 
velthuijsen
Guest
Posts: n/a
 
      04-16-2004
Apricot <> wrote in message news:<>. ..
> #include <iostream>
> #include <string>
> #include <map>
> using namespace std ;
> class tst
> {
> public :
> tst() { cout << "tst::constructor" << endl ; }
> tst(const tst & that) { cout << "tst::copy constructor" << endl ;
> }
> tst & operator =( const tst & that ) { cout << "tst:perator ="
> << endl ; }
>
> ~tst() { cout << "tst::destructor" << endl ; }
> } ;
> int main()
> {
> map < string , tst > a ;
> tst e ;
> a.insert(pair < string , tst > ("standard",e) ) ;
>
> system("pause") ;
> return 0 ;
> }
> ///// Output ////////////


> tst::constructor
> tst::copy constructor
> tst::copy constructor
> tst::copy constructor
> tst::destructor
> tst::destructor


From what I understand all the STL containers get populated by
copying. This means that the only time the constructor gets called is
when you do
tst e;


a.insert(pair < string , tst > ("standard",e) );
First you create a (temporary) pair which gets populated by copying
("standard", e) into it.

In the second step the internal workings of the map implementation you
seem to be using creates a pair for internal use (2nd temporary in
this case) by copying ("standard", e) from the first pair into it.

Finally at the third step the map creates a node in the binary tree
that is populated by copying the 2nd temporary pair into it. (Note: it
is not required that any implementation uses a binary tree to store
map data, it just happens that all the implementations I know do it
that way)

fourth step is destroying the 2nd temporary pair (as seen by your
tst::destructor output), the one created by the insert action

fifth step is destroying the first temporary pair, the one you
explicitly created.


Hopefully the next bit of code can make it a bit clearer. replace your
main with it (it should also give you two more destructor calls).
Code:
int main()
{
{
map < string , tst > a;
cout << "map created\n" ;
tst e ;
cout << "tst e created\n" ;
std::pair<string, tst> mep("standard", e);
cout << "pair created\n";
a.insert(mep) ;
}

cout << "mash keyboard to continue" << endl;
cin.get();
return 0 ;
}
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Three Mobile --> Skype on three (Non-three [Symbian - Nokia] handsets) Harry Stottle UK VOIP 0 01-05-2010 08:59 AM
conditions for automatic generation of default ctor, copy ctor,and default assignment operator (operator) puzzlecracker C++ 8 04-15-2008 09:56 PM
copy ctor vs default ctor subramanian100in@yahoo.com, India C++ 2 08-15-2007 10:49 AM
ctor/dtor calls and ctor init seq Grizlyk C++ 8 11-29-2006 06:35 AM
Templates, copy ctor and type-conversion ctor NVH C++ 8 07-06-2006 07:19 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57