Archived

This topic is now archived and is closed to further replies.

jdhardy

std::vector type requirements

Recommended Posts

jdhardy    469
Okay, when an onject is in a std::vector, what does it require for copying? Copy constructor, assignment operator(operator=), or both? And if you have a copy constructor, does the compiler generate the assignment operator automgically?

Share this post


Link to post
Share on other sites
jdhardy    469
Default constructable: check
Assignable: sorta-check

The class in question (CPlayer) is inherited from another class (CObject, an almost-ABC). Now, I figured out to write the copy constructor for CPlayer, but operator= is a bit of a problem, due to the inheritance and all. Which does std::vector use (copy ctor or operator=)? Or is that one of those annoying unspecified and implementation dependent things?

Share this post


Link to post
Share on other sites
Fruny    1658
quote:
Original post by ze_jackal
Which does std::vector use (copy ctor or operator=)? Or is that one of those annoying unspecified and implementation dependent things?


It depends on the operation. When creating new elements as copy of other (e.g. vector::assign) it''ll use the copy constructor. When assigning one to the other (e.g. most algorithms), it''ll use the assignment operator.

That doesn''t change the fact that both must be implemented, and with the same semantics.


Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]

Share this post


Link to post
Share on other sites
jdhardy    469
Okay, this helping to clear up alot. Thanks. Which brings me to my final question: How can I implement operator= when the class I'm trying to copy inherits from another class? I need the data in the parent, but I don't want to have to paste the same code into the assignment operator for each derived class (When the parent is called CObject, you can tell there is going to be ALOT of derived classes) Is there an easy way to do it, or am I stuck with ctrl-c & ctrl-v?

P.S. Should std::vector:: push_back() cause either to be called? I'd imagine if it had to resize the array, but otherwise?

EDIT: Stupid smileys

[edited by - ze_jackal on October 22, 2002 8:11:00 PM]

Share this post


Link to post
Share on other sites
Nypyren    12061
derived class function body:

CPlayer CPlayer::operator=(const CPlayer &rhs)
{
CObject::operator=(rhs);
}

... I think you can do that. It should call the CObject's = operator using "this" to let that function do the work.


To find out first-hand when the copy ctor/ operator='s are being called, just put some kind of print-out line inside the copy ctor and op=.

I seem to remember there are a varying number of copy ctor calls (and no op=) each time you push_back a class into a vector (this is why I use a vector of object * when I need speed).

If you use pointers to objects, you won't need either copy ctor or op=, since just the pointer value is messed with.


  
#include "stdio.h"
#include <vector>
using std::vector;

class blarg
{
public:
int i;

blarg(int _i):i(_i) {}

blarg(const blarg &b)
{
printf("Copy\n");
i = b.i;
}

blarg operator=(const blarg &b)
{
printf("Op=\n");
i = b.i;
return *this;
}
};

typedef vector<blarg> vblarg;

void main()
{
printf("Creating vector.\n");
vblarg a;

for (int i=0; i<10; i++)
{
printf("Pushing.\n");
a.push_back(blarg(i));
}

printf("Cleanup.\n");
}


Notice that sometimes there are only 2 calls (one in the push_back like, and one when the vector copies the data into it's storage space), and sometimes it resizes the vector's space, resulting in more copy ctors firing.

(had to edit this to fix a problem with HTML on the page)


[edited by - Nypyren on October 22, 2002 11:03:27 PM]

Share this post


Link to post
Share on other sites
Fruny    1658
Yes, you can do that, that's an explicit call to a base class member function.


CPlayer& CPlayer::operator=(const CPlayer &rhs) // note - return by reference
{
if( this == &rhs ) // self-assignment guard - performance AND correctness
return *this;

CObject::operator=(rhs);

playerdata = rhs.playerdata;

// run init code

return *this
}

CPlayer::CPlayer( const CPlayer& rhs )
: CObject( rhs ), // Don't forget to initialize the base class
playerdata( rhs.playerdata )
{
// run init code
};


Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]


[edited by - Fruny on October 22, 2002 11:09:03 PM]

Share this post


Link to post
Share on other sites
jdhardy    469
Thanks so much for your help, I finally got everything working. Turns out the compiler could generate usable assignment operators, but I might as well hardcode ''em now that I know how to do it.
quote:

CPlayer CPlayer::operator=(const CPlayer &rhs)
{
CObject::operator=(rhs);
}


That is going into my ''Cool shit I never would have thought was possible'' file. That could come in handy.

quote:

To find out first-hand when the copy ctor/ operator=''s are being called, just put some kind of print-out line inside the copy ctor and op=.



I take the time to build a class to output debug info to a log from anywhere, and litter my code with debug prints at the first sign of a bug, and I STILL DIDN''T THINK TO DO THAT! Sometimes the easiest way to find the solution is right under your nose. I guess that''s what the forums are for.

Share this post


Link to post
Share on other sites