class foo {
public:
foo() { assert(!"foo constructor"); }
~foo() { assert(!"foo destructor"); }
};
...
std::vector<foo> fooVec;
fooVec.push_back(foo());
The above code generates one cunstructor assert, followed by THREE destructors! Zuh?
Destructors and Vectors...
So I noticed that when I add objects to a vector, their destructors are being called more than they should be... see the following...
With your code I get one constructor call, followed by two destructor calls, which makes sense -- one constructor/destructor pair for the temporary, and a second destructor when the vector goes out of scope. Are you sure this is a minimal example that demonstrates the behavior you describe?
Quote:Original post by ZealousEngineWell, all of the constructors except the first are probably copy constructors. That is, a constructor with this signature:
The above code generates one cunstructor assert, followed by THREE destructors! Zuh?
foo(const foo& p) { assert(!"foo copy constructor");}
The first constructor is called when you make the temporary foo object. A copy constructor is probably called when you add the temporary to fooVec. I can't actually think of why another copy constructor is called though. I'm sure someone else has already finished explaining this better than I did or at least someone will soon. Hope this helps.
Just tested again, still getting ONE constructor and THREE destructores... The only code is what I posted above... are you sure you only get two destructors?
Why wouldnt it be a 1 to 1 ratio of constructors to destructors though? I have a lot going on in the constructors (they allocate new objects for example), and the fact that things ARE NOT 1 to 1 is causing all kinds of bugs :(
Why wouldnt it be a 1 to 1 ratio of constructors to destructors though? I have a lot going on in the constructors (they allocate new objects for example), and the fact that things ARE NOT 1 to 1 is causing all kinds of bugs :(
Quote:Original post by ZealousEngine
Just tested again, still getting ONE constructor and THREE destructores... The only code is what I posted above... are you sure you only get two destructors?
Why wouldnt it be a 1 to 1 ratio of constructors to destructors though?
Did you try adding the copy constructor code I showed you? The compiler makes one for you, but it won't print, obviously.
Quote:Original post by ZealousEngineIt might be a 1:1 ratio, but your code only checks for one particular kind of constructor.
Why wouldnt it be a 1 to 1 ratio of constructors to destructors though?
Try testing with this, like nobodynews suggested:
class foo {public: foo() { assert(!"foo constructor"); } foo(const foo&) { assert(!"foo constructor"); } ~foo() { assert(!"foo destructor"); }};
Quote:Original post by ZealousEngineSounds like your classes don't implement the copy constructor or assignment operator, which will cause bugs for you if the default constructor / destructor are non-trivial.
I have a lot going on in the constructors (they allocate new objects for example), and the fact that things ARE NOT 1 to 1 is causing all kinds of bugs :(
Ok I think I see now, so I am seeing one constructor, then TWO copy constructors (I assume two since the vector always allocates twice the space needed right?), then followed by 3 destructors (one for the temporary, and two for the vector).
I wonder though, is there anyway to have a list/vector of objects, and grow things WITHOUT having to create a temporary object?
*I think the bug I was noticing was because I was creating a new unrelated object in the constructor, and then deleting it in the destructor. I guess this caused problems when the vector tried to copy stuff around?
I wonder though, is there anyway to have a list/vector of objects, and grow things WITHOUT having to create a temporary object?
*I think the bug I was noticing was because I was creating a new unrelated object in the constructor, and then deleting it in the destructor. I guess this caused problems when the vector tried to copy stuff around?
Just to clarify, if you do not implement the copy constructor yourself, the compiler will implement one for you.
There is a "rule" in C++ called the rule of "three", which is appropriate in this case.
If you want to avoid the copy constructor, you can store pointers to the object (or better yet boost::shared_ptrs) instead.
There is a "rule" in C++ called the rule of "three", which is appropriate in this case.
If you want to avoid the copy constructor, you can store pointers to the object (or better yet boost::shared_ptrs) instead.
Well I am trying to use the vector as a sort of reusable pool, in order to keep all my objects grouped together in memory. Thus I cant really just store pointers.
So how should I implement the following class...
..in order to avoid havoc when the vector copies things around?
So how should I implement the following class...
class foo {public: foo() { mObj = new Obj; assert(!"foo constructor"); } ~foo() { delete mObj; assert(!"foo destructor"); } foo(const foo& p) { assert(!"foo copy constructor"); }};
..in order to avoid havoc when the vector copies things around?
Quote:Original post by ZealousEngine
Ok I think I see now, so I am seeing one constructor, then TWO copy constructors (I assume two since the vector always allocates twice the space needed right?)
One is because the object is copied into the vector, and the other is presumably because the vector resizes and the object gets copied into the new allocation.
Vectors allocate space exponentially, but there is nothing in the spec that mandates a factor of 2. Also, the allocation size doesn't affect things in the way that you suggest: there is extra allocated *space*, but if you only put in one *element*, then there is only one element, which gets copied in once.
However, every time the vector re-allocates, it must copy every element from the old allocation into the new allocation and call destructors for the elements in the old allocation; then it carries on using the new allocation as if nothing had happened.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement