TestDelete::TestDelete(int i) {
this->i = i;
std::cout <<"TestDelete constructor for "<<this->i<<"\n";
}
TestDelete::~TestDelete() {
std::cout <<"TestDelete destructor for "<<this->i<<"\n";
}
int main () {
std::vector<TestDelete> pt;
pt.push_back(TestDelete(1));
pt.push_back(TestDelete(2));
return 0;
}
以上代码段输出如下
1的TestDelete构造函数
1的TestDelete析构函数
2的TestDelete构造函数
1的TestDelete析构函数;
2的TestDelete析构函数;
1的TestDelete析构函数;
2的TestDelete析构函数;
我理解push_back
的实现基于copy-swap概念,因为它会调用temperory对象的构造函数和析构函数。但是如果你注意到对object1
的析构函数进行了额外的调用。
有人能解释一下这里发生了什么吗?
答案 0 :(得分:1)
您正在破坏Rule of 3并且您的某个对象正在被复制,并且您正在查看该副本的析构函数。
如果添加复制构造函数和带有日志记录的复制赋值运算符,您将看到可理解的行为。
编辑:由于人们对评论中的这个答案感到困惑 - 这只是为了表明没有任何事情错误,只是如果你添加CC / CAO记录你会看到所有对象都被正确创建/分配/销毁。程序正确性不需要CC / CAO。下面有一个更好的答案,为什么std :: vector可能按照你在下面看到的顺序创建/分配/销毁。对由此引起的任何混乱道歉。
答案 1 :(得分:1)
让我们看看您的实施可能在做什么:
std::vector<TestDelete> pt;
创建大小为0的向量。
pt.push_back(TestDelete(1));
重新分配大小为1的向量。通过复制构造(移动构造)临时添加新元素。
pt.push_back(TestDelete(2));
重新分配大小为2的向量。这意味着复制构造(或移动构造)先前创建的元素,并删除原始元素。通过复制构造(移动构造)临时添加新元素。
Here is a live example,也有改进功能,可防止矢量重新分配。请注意,临时工仍在被破坏,这让我感到惊讶;我猜编译器可以删除副本。
答案 2 :(得分:0)
这是因为std::vector
的调整大小政策。然后它被填满,它会因某种因素而增长。这需要新的内存分配+旧的内存释放(,因此析构函数的调用)。
例如,如果您事先保留内存,则不会调整大小:
$ cat main.cpp
#include <iostream>
#include <vector>
class TestDelete {
public:
TestDelete(int);
~TestDelete();
int i;
};
TestDelete::TestDelete(int i) {
this->i = i;
std::cout <<"TestDelete constructor for "<<this->i<<"\n";
}
TestDelete::~TestDelete() {
std::cout <<"TestDelete destructor for "<<this->i<<"\n";
}
int main () {
std::vector<TestDelete> pt;
pt.reserve(10); // reserve memory for 10 objects
pt.push_back(TestDelete(1)); // so no resize would be needed
pt.push_back(TestDelete(2));
return 0;
}
$ ./a.out
TestDelete constructor for 1 // temporary object constructed
TestDelete destructor for 1 // temporary object destructed
TestDelete constructor for 2 // temporary object constructed
TestDelete destructor for 2 // temporary object destructed
TestDelete destructor for 1 // vector destructed
TestDelete destructor for 2 // vector destructed