我正在学习理解类构造函数和析构函数。我编写了一个小型控制台代码,将一个类实例添加到向量中。这一切都很好,但我不明白的是,在向量中添加一个对象会触发两次析构函数。这一切为什么要发生?
如果我不添加任何对象,向量本身就不会触发构造函数或析构函数,那么为什么会发生两次呢?
有人能解释一下为什么会发生这种事吗?
#include <cstdio>
#include <vector>
class Test
{
private:
int value;
public:
Test()
{
printf("\nClass constructor triggered.");
};
~Test()
{
printf("\nClass desctructor triggered.");
}
};
int main()
{
std::vector<Test> container;
container.push_back( Test() );
return 0;
}更新:我向类添加了更多信息,以便获得更具体的输出,但是现在我注意到,随着向量的每一次添加,移动构造和析构函数调用都会增加。这些调用的数量是否与向量内的对象数量或正在发生的情况有关?我在泄密吗?抱歉如果问题太蠢了。以下是添加的代码:
#include <cstdio>
#include <vector>
class Test
{
private:
int value;
public:
// Constructor
Test(int v=0)
{
value = v;
printf("\n\n%i", value);
printf("\nClass constructor triggered.");
};
// Copy-move constructor
Test(Test&&)
{
printf("\nClass move-constructor triggered.");
};
// Destructor
~Test()
{
value = 0;
printf("\nClass desctructor triggered.");
}
};
int main()
{
std::vector<Test> container;
container.push_back( Test(1) );
container.push_back( Test(2) );
container.push_back( Test(3) );
container.push_back( Test(4) );
printf("\n\nPushback complete!");
return 0;
}发布于 2015-10-09 10:12:50
向量包含通过push_back()添加到它的对象的副本。第一次析构函数调用是由于在包含对push_back()的调用的完整表达式末尾创建的临时销毁。当向量本身被销毁时,第二析构函数是由正在被销毁的向量内的副本引起的。
您可以通过在main()中添加诊断信息来说服自己
int main()
{
std::vector<Test> container;
container.push_back( Test() );
printf("\nThis is before the vector is destroyed...");
return 0;
}您可以在这个http://coliru.stacked-crooked.com/a/19d3e574e30be028中观察输出。
您的向量包含的副本是通过为类调用自动生成的移动构造函数(而不是使用默认构造)创建的,这就是为什么您没有看到相应的构造诊断。
如果您定义了自己的move构造函数(或复制构造函数,如下所示)来发出诊断,则输出将更接近您预期的结果:
Test(Test const&)
{
printf("\nCopy construction triggered.");
};再说一遍,http://coliru.stacked-crooked.com/a/5a11d66e9434cc84。
发布于 2015-10-09 10:13:07
为了简单起见,让我们假设您正在使用C++03,而且移动语义还不可用。
添加复制构造函数,以确保它也被触发。
Test(const Test&)
{
printf("\nClass copy constructor triggered.");
};输出
Class constructor triggered.
Class copy constructor triggered.
Class destructor triggered.
Class destructor triggered.因此,有两个对象被构造/破坏。
粗略地说,您的代码等于
int main()
{
std::vector<Test> container;
Test test; // first object created
container.push_back(test); // second object created by copying
return 0;
}发布于 2015-10-09 10:13:19
push_back()不触发任何析构函数(在本例中)。
对Test的析构函数的两个调用是:
1-因为您将一个临时对象传递给push_back(),所以当push_back()完成时,该对象就会被销毁。
2-当程序结束时,vector就会被破坏,所以它就是内容
https://stackoverflow.com/questions/33035512
复制相似问题