I can't figure out how to copy class objects into a vector

Started by
4 comments, last by gapern 15 years, 8 months ago
Ok so i've got a class called thing. Here's the constructor's parameters.

thing(string name,int x,int y,int whichscene,bool pickedup,bool canbepickedup,string pngname,string pnginvicon,int filesize,string worlddescription,string invdescription)
Here's my object I want to copy into the vector.

thing tree1("Tree",300,240,1,false,false,"..\\images\\tree.png","..\\images\\tree.png",1,"This is a tree","NULL");
Here is my vector

vector<thing> allthings;
allthings.resize(50);
That should be all the relevant code. What i'm trying to accomplish is this.

allthings[0].name = tree1.name;
allthings[0].x = tree1.x;
And so on for every data member set in the tree1 object. Here's the code I wrote to try and accomplish that.

allthings[0] = tree1;
This gives me errors.

c:\program files\microsoft visual studio 9.0\vc\include\vector(713) : error C2512: 'thing::thing' : no appropriate default constructor available


c:\program files\microsoft visual studio 9.0\vc\include\vector(712) : while compiling class template member function 'void std::vector<_Ty>::resize(unsigned int)'
        with
        [
            _Ty=thing
        ]


c:\documents and settings\kenny\desktop\adventure\adventure\adventure.cpp(22) : see reference to class template instantiation 'std::vector<_Ty>' being compiled
        with
        [
            _Ty=thing
        ]

I don't know why i'm getting those errors or what they even mean. That second one looks like it's complaining about my vector.resize(), but I don't see anything wrong with it. The other two i'm just completely clueless about what they mean. Any ideas?
Advertisement
I THINK that the problem is that you may be missing a copy constructor for the thing class; if you don't supply your own copy constructor, the compiler will substitute a default which likely doesn't do what you want and it usually doesn't perform a deep copy. Here's something which may help, and here's what MSDN has to say about error C2512.

The purpose of a copy constructor is a constructor which allows you to do a "deep copy" of the object in question, that is to say that you're creating a brand new copy of it in a separate area of memory as opposed to simply pointing to the original.

I'll leave it to someone else to supply the code because I'm tired and I've forgotten how to do it.

EDIT: the other alternative is to create the objects dynamically and store the pointers in the vector as opposed to the objects themselves. This probably reduces overheads, come to think of it, especially if it comes to the vector being accessed by multiple parts of the program; it's likely more efficient to dereference the pointer as opposed to storing a whole, live object in there. At least that's the way I'd do it.
Those errors were caused by me not having a default constructor. Now that I put one in things appear to be working fine. I can do this

draw(allthings[0].x,allthings[0].y,tree,screen);


and my tree is drawn at the proper location. I really hate c++ sometimes. One line of code and it stops me for an hour+.
Quote:Original post by gapern
I really hate c++ sometimes. One line of code and it stops me for an hour+.

C++ assumes that the programmer is always right. Maybe it's not the right language for you?
Quote:One line of code and it stops me for an hour+.


Well, the error message told you exactly and quite clearly what was wrong.

But you have to know the difference between the vector's resize and reserve method. resize changes the size of the vector, creating new instances using the default constructor by default (but you can give it a non-default-constructed instance too). reserve simply sets aside memory but doesn't construct any objects.

So if you don't want to end up with half a vector full of default-constructed dummy objects (if it turns out that you won't be putting 50 items in it) you could use the more usual way to put stuff in a vector:

vector<thing> allthings;allthings.reserve(50); //optionally reserve some memory upfrontallthings.push_back(tree1);


It is also strange that you would assign members one by one. The compiler generates an operator= for classes/structs automatically that already does exactly that. If you do it that way because not all members are simply assigned, you'll probably need to overload the assignment operator and write a copy constructor and destructor yourself, otherwise the objects won't behave well in a vector anyway.


Quote:
C++ assumes that the programmer is always right. Maybe it's not the right language for you?


No I enjoy it, I just like to complain.

Quote:
Well, the error message told you exactly and quite clearly what was wrong.


You are right about that first error being clear. But I hadn't encountered it before, and I really wasn't very familiar with constructors. From now on I will always put in a default constructor. Those other 2 errors were gibberish though.

Quote:
So if you don't want to end up with half a vector full of default-constructed dummy objects (if it turns out that you won't be putting 50 items in it) you could use the more usual way to put stuff in a vector:


That is what I am doing now. It's better than what I was doing. I didn't realize push_back resized the vector for me.

Quote:
It is also strange that you would assign members one by one. The compiler generates an operator= for classes/structs automatically that already does exactly that. If you do it that way because not all members are simply assigned, you'll probably need to overload the assignment operator and write a copy constructor and destructor yourself, otherwise the objects won't behave well in a vector anyway.


I'm assuming you are talking about this line of code that I posted.

allthings[0].name = tree1.name;allthings[0].x = tree1.x;


That was just an example of what I wanted to do, but I knew it was horrible and because of my lack of a default constructor this was not working.

allthings[0] = tree1;


Now it does work and that is what I am doing.

This topic is closed to new replies.

Advertisement