我正在学习理解类构造函数和析构函数.我编写了一个小的控制台代码,用于将一个类实例添加到向量中.一切都很好,花花公子,但我无法理解的是,在向量中添加一个Object会触发析构函数两次.为什么会这样?
如果我不添加任何对象,向量本身不会触发构造函数或析构函数,那么为什么它会发生两次呢?
谁能解释为什么会这样?
#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;
}
Run Code Online (Sandbox Code Playgroud)
更新:我向类中添加了一些更多的信息,以便我获得更具体的输出,但是现在我注意到,每次添加到向量时,移动构造和析构函数调用都会增加.这些调用的数量是否与向量中的对象数量相关或发生了什么?我有泄漏吗?对不起,如果太愚蠢的问题.以下是添加的代码:
#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;
}
Run Code Online (Sandbox Code Playgroud)
您的向量包含您通过其添加的对象的副本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;
}
Run Code Online (Sandbox Code Playgroud)
您可以在此实例中观察输出.
您的向量包含的副本是通过为您的类调用自动生成的移动构造函数(而不是使用默认构造)来创建的,这就是您没有看到相应构造诊断的原因.
如果您定义了自己的移动构造函数(或复制构造函数,如下所示)来发出诊断,那么输出将更接近您的期望:
Test(Test const&)
{
printf("\nCopy construction triggered.");
};
Run Code Online (Sandbox Code Playgroud)
再一次,实例.