std::vector type requirements

Started by
6 comments, last by jdhardy 21 years, 6 months ago
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?
Advertisement
Type requirements : Default constructible and Assignable.

The copy constructor and operator= are indissociable.
If you have one, you must also write the other (no magic).

Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
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?
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 ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
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]
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]
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]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
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.

This topic is closed to new replies.

Advertisement