道歉,如果问题听起来很愚蠢,我就是在关注SO的专家并亲自尝试一些例子,这就是其中之一。我确实尝试过搜索选项,但没有找到这种答案。
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.
}
为什么类的析构函数被调用两次?
答案 0 :(得分:42)
要添加元素,请在临时对象上调用复制构造函数。在push_back()
临时对象被销毁之后 - 这不是第一个析构函数调用。然后vector
实例超出范围并销毁存储的所有元素 - 这是第二个析构函数调用。
答案 1 :(得分:25)
这将显示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());
}
答案 2 :(得分:4)
当发送到push_back
的临时值被销毁时,析构函数被调用一次,而t
中的元素被销毁时,析构函数被调用一次。
答案 3 :(得分:2)
有两个析构函数调用,因为有两个对象:push_back
的参数和vector
t
中新添加的元素。
STL containers存储副本。在您的示例中,由push_back
添加到vector
的元素是从传递给push_back
的参数构造的副本。参数为A()
,这是一个临时对象,请参阅here (variant 4)。
稍微扩展一下答案,尽管你没有明确要求它:知道临时被摧毁的时间可能会有用。标准(N4140)在12.2 p3中很清楚:
...临时对象作为评估的最后一步被销毁 full-expression(1.9)(词法上)包含它们的点 被创造了......
旁注:如果使用emplace_back
,则只有一个对象。容器中的新元素直接由emplace_back的参数构造。许多STL容器在C ++ 11中学习了一个emplace变种。
答案 4 :(得分:0)
最有可能的是,您的对象副本正在创建中。因此,复制对象和原始对象的析构函数使call-count = 2。
示例:即使您将对象引用传递给某个类,也会在内部调用copy-constructor。为避免这种情况,子类(您要将父引用传递给它)必须为;
Parent *const &p parentRef; //Child.h
然后,父对象将作为;
传递// Parent.cpp
Parent *parentObj = this;
Child *childObj = Child(parentObj);
此外,您可以通过覆盖来调试copy-constructor invokation;
Parent(const Parent& object){
cout <<"copy called.." << endl;
}
...
更多信息@stackoverflow@