#### Archived

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

# STL question

## Recommended Posts

Hi all, Im working on a project right now that heavily utilizes the STL. (mostly vectors). I read somewhere that the STL invokes copy constructors when dealing with the data it stores. My question is... What are copy constructors? are they slow? should I use use "new" and "delete" instead with the containers? I read that it dosent matter much when dealing with small data like ints. but I have classes that have vectors that own vectors which own vectors. These can grow very large... should I really be "copy constructing" things this big? where do I draw the line? I would really hate to rewrite tons of code, plus working with new and delete makes my code much less clean (not to mention complicated , and memleak vunerable). but im willing to sacrafice simplicity for speed. One more thing... NEHE is great and all, but where do I find out how to optimize the living hoohaa out of opengl? or anything else for that matter ( ex: casting an float to an int with memory addresses instead of "int SomeInt = (int)SomeFloat;" )

##### Share on other sites
Russell    118
A copy constructor simple creates a copy of a class. For example if you have a class named MyClass, then you could make a copy of an instance of this class by the following:

  MyClass a;a.Initialize();Myclass b(a); // Creates a copy of a and stores it in b

Now, what you want to avoid is passing these kinds of data structures to functions "by value". For example, if you have a function:

  void MyIntFunction(int n);

it''s ok to pass a copy of that int, because an int is only 32-bits in size, and you can pass a copy of that without it slowing your program down very much. Now let''s say you have another function:

  bool MyVectorFunction(vector v);

When you pass a vector to this function, the function will create a copy of the vector and then use that copy inside the function. If you have a small vector of 10 things, then you probably won''t be able to notice a delay in your program. But let''s say that you have a vector with 10 million things in it. That means that you have to copy over 10 million things into the copy of your vector just to pass it to the function. I''ll give you an example of how bad this could get:

  bool MyVectorFunction(vector v){ if(v.size() > 1000) return false; return true;}

In this function, all that is done is that it checks the size of the vector and then returns true or false based on that size. Pretty simple. But if your vector has 10 million things in it, then your function will have to copy over 10 million things, probably delaying your program for a small (noticable) amount of time, and it will do all of that work, just to see if the vector is bigger than 1000 elements. So the point I''m making here is, you''re doing a LOT of uneeded work (copying 10 million things) for being able to do just a little work.

So how do we solve this problem? There are basically two ways that I''m aware of. You can pass a pointer to your vector, or you can pass your vector by reference. I would choose to pass it by reference just for simplicity''s sake, but I''ll show you both ways of doing it.

Passing a pointer
  bool MyVectorFunction(vector * v){ if(v->size() > 1000) return false; return true;}

Passing by reference
  bool MyVectorFunction(vector & v){ if(v.size() > 1000) return false; return true;}

The reason I suggested doing it by reference was that you don''t have to change anything in your function. The only thing that changes is the way it works, which should be FASTER. If you do it using a pointer, then you need to know how pointers work, and it''s easier to mess something up using a pointer. Like if you accidentally mean to do a ++ on your object and you do a ++ on your pointer, expect chaos. I''d go with a reference, so you can avoid any potential headaches of messsing up your pointer.

Russell

##### Share on other sites
Thanks man I really appriciate the support =)

all my big data funtions use pointers so I think ill be ok. So I guess using new and delete is only usefull when you want STL containers to contain similar items (ex: Iheritance)

// like so...

class boat { }

class ship public: boat { }

std::vector watercrafts;

watercrafts.push_back( new boat );
watercrafts.push_back( new ship );

// somthing like that I think...

##### Share on other sites
Genre    122
To my knowledge, vector and other STL are self contained... No need for new or delete, they mabage this by themselves...

No sure if you need a copy constructor to pass a vector as an argument though, but what I do mostly is pass it by reference. One thing I noticed laast time I used vectors and such is that you can create two vectors of the same type and assign them to one another. Example:

{
vector a;
vector b;

void InitVector(a); // inits the vector with god knows what...

b = a;
}

I *THINK* it works... Will have to get back on you about this. I know you can copy object in this manner and it will do a BITWISE copy of it. That is where copy constructors cone in handy, if you class contains pointers, he will simply copy the address and both classes will be pointing to the same memory location and this is bad...

ADDENDUM: Just checked that code fragment up there... It worked in one of my app previously... So... It seems the STL do implement there own set of copy constructors also.

Cheers!

Any way... Good luck.

##### Share on other sites
Stoffel    250
quote:
Original post by Genre
To my knowledge, vector and other STL are self contained... No need for new or delete, they mabage this by themselves...

This is true. However, if your container contains pointers, the client (you) is responsible for making sure they point to something that makes sense. This often means dynamically allocating objects as you push pointers to them into the vector, deleting them on the way out.

##### Share on other sites
Genre    122
I am not sure about this... I have assigned one vector to another in some of my past applications and they did contain pointers. I had no problems. I know that with objects, you need to provide a copy constructor if they have pointers (or allocate some memory) else a bitwise copy will be made and both pointers (in the objects) will point to same location (we cant have that).

But for the vector (and other STL) I have been able to assign object vectors to other object vectors of the same type (even if they contained pointers) and I had no problems.

I would post the code here, but it is kinda large...

Anyway, I ll check on this a little more.

Cheers!

BTW... here is my code sample...

void CalculationDriver(vector& RefSiteVector, vector& RefConnectorVector)
{

// Copy the vectors in temprorary ones
vector TmpSiteVector = RefSiteVector;
vector TmpConnectorVector = RefConnectorVector;

// Create our iterators
vector::iterator pCurrentTmpSiteVector;
vector::iterator pIndexTmpSiteVector;

this is the important part... CSite is a class... It is defined here:

/ Here we define the class of the Sites. Sites are 3D positions with charges.
class CSite {

// Info used by the program
long int SiteTag;
vector ConnectorTag;

// Info defining the class
CVector SitePosition;
CVector SiteSpeed;
double fCharge;
double fWeight;

// Info defining the site state
bool IsSiteSurface;
bool IsSiteFixed;

public:
// Constructor
CSite(long int TmpSiteTag,
CVector TmpSitePosition,
double TmpCharge,
double TmpWeight,
vector TmpConnectorTag,
bool TmpIsSiteFixed,
bool TmpIsSiteSurface);

// Member functions that deal with the Program Info
vector GetConnectorTag() { return ConnectorTag;}
long int GetSiteTag() { return SiteTag;};

// Member functions that deal with the class info
void SetSitePosition(CVector TmpSitePosition) { SitePosition = TmpSitePosition;}
void SetSiteSpeed(CVector TmpSiteSpeed) { SiteSpeed = TmpSiteSpeed;}
CVector GetSitePosition() { return SitePosition;}
CVector GetSiteSpeed() { return SiteSpeed;}
double GetCharge() { return fCharge;}
double GetWeight() { return fWeight;}

// Member functions getting state of site
bool GetIsSiteSurface() { return IsSiteSurface;}
bool GetIsSiteFixed() { return IsSiteFixed;}
};

So what I did, I copied a vector containing a certain number of objects of the CSite type to another vector that I just created. Notice that these CSite objects each contain a vector as a member variable. This code works perfectly.

Edited by - Genre on December 19, 2001 3:13:07 PM

Edited by - Genre on December 19, 2001 3:16:28 PM

##### Share on other sites
Stoffel    250
quote:
Original post by Genre
I am not sure about this... I have assigned one vector to another in some of my past applications and they did contain pointers. I had no problems.

Of course. The original vector contained pointers to objects that actually exist. The same pointers anywhere else (even another vector) also make sense. Were these stack objects? If so, no problem. If they were dynamically allocated somewhere, you had to new them at one time, and if you didn''t delete them, they would leak.

The pointers don''t care that they''re in a vector, and the vector doesn''t care if it contains pointers or objects.
quote:

I know that with objects, you need to provide a copy constructor if they have pointers (or allocate some memory) else a bitwise copy will be made and both pointers (in the objects) will point to same location (we cant have that).

Depends on the situation, but generally true.
quote:

But for the vector (and other STL) I have been able to assign object vectors to other object vectors of the same type (even if they contained pointers) and I had no problems.

But you have had N calls to your object''s copy ctor. That may be OK, but the real danger with vectors is that if you insert/remove from the beginning, or the vector outgrows its bounds, it will internally copy itself and all of its objects. Not a big deal if it''s a vector of pointers (easy to copy 4 bytes), could be a huge deal if they are large objects.