Apologies if the question sounds silly, I was following experts in SO and trying some examples myself, and this is one of them. I did try the search option but didn't find an answer for this kind.
class A
{
public:
A(){cout<<"A Contruction"<<endl;}
~A(){cout<<"A destruction"<<endl;}
};
int main()
{
vector<A> t;
t.push_back(A()); // After this line, when the scope of the object is 开发者_高级运维lost.
}
Why is the destructor of the class called twice ?
To add the element a copy constructor is invoked on a temporary object. After the push_back()
the temporary object is destroyed - that't the first destructor call. Then vector
instance goes out of scope and destroys all the elements stored - that's the second destructor call.
This will show you what's happening:
struct A {
A() { cout << "contruction\n"; }
A(A const& other) { cout << "copy construction\n"; }
~A() { cout << "destruction\n"; }
};
int main() {
vector<A> t;
t.push_back(A());
}
The destructor is called once when the temporary sent to push_back
is destroyed and once when the element in t
is destroyed.
There are two destructor calls because there are two objects: the argument to push_back
, and the newly added element within vector
t
.
STL containers store copies. In your example the element added to the vector
by push_back
is copy constructed from the argument passed to push_back
. The argument is A()
, which is a temporary object, see here (variant 4).
Expanding the answer a bit, altough you havent explicitely asked for it: It might be useful to know when the temporary is destroyed. The standard (N4140) sais it pretty clearly in 12.2 p3:
... Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created...
Side note: If you use emplace_back
there is only one object. The new element in the container is directly constructed from the arguments to emplace_back. Many STL container learned an emplace variant in C++11.
Most probably, copy of your object is getting created. Because of which, the destructor for the copied-object, and for the original-object makes the call-count=2.
Example: Even though, you are passing the object reference, to some class, this internally would invoke the copy-constructor. To avoid this, the child-class (to which you are passing the parent reference, must be as;
Parent *const &p parentRef; //Child.h
Then, the parent object will be passed as;
// Parent.cpp
Parent *parentObj = this;
Child *childObj = Child(parentObj);
Additionally, you can debug the copy-constructor invokation, by overriding;
Parent(const Parent& object){
cout <<"copy called.." << endl;
}
...
More info @stackoverflow@
精彩评论