C++ 第一次破坏来自哪里?
我试图练习以下代码:C++ 第一次破坏来自哪里?,c++,C++,我试图练习以下代码: #include <iostream> #include <vector> using namespace std; class A { public: virtual void f(){cout<<"A"<<endl;} virtual ~A(){cout<<"destruct A"<<endl;} }; int main() { A o1,o2; vector <
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
virtual void f(){cout<<"A"<<endl;}
virtual ~A(){cout<<"destruct A"<<endl;}
};
int main()
{
A o1,o2;
vector <A > O;
O.push_back(o1);
cout<<"1"<<endl;
O.push_back(o2);
cout<<"test"<<endl;
return 0;
}
弄不清楚第一个析构函数来自何处。让构造函数和析构函数打印对象的内存地址,这样就可以跟踪对象的生存期:
virtual void f() { cout << "A: " << std::hex << this << endl; }
virtual ~A(){ cout << "destruct A: " << std::hex << this << endl; }
virtual void f(){cout您的向量在第二次调用push_back时重新分配了其内存缓冲区。这要求将其中的对象复制到新缓冲区,并销毁原始对象
如果您调用O.reserve(2)
在插入任何对象之前,这将为向量提供足够的空间容纳两个对象。因此,它不需要重新分配,并且在main结尾之前不应该看到任何破坏。从技术上讲,如果编译器吸吮并生成不必要的副本,则可能会有更多的破坏。但是,从您目前所展示的情况来看,我认为t似乎没有这样做。将语句打印到复制构造函数后,我们得到以下结果:
constructor A(0x7fff6e21e800)
constructor A(0x7fff6e21e7f8)
copy A(0x10e700910: From 0x7fff6e21e800)
1
copy A(0x10e700920: From 0x10e700910)
copy A(0x10e700928: From 0x7fff6e21e7f8)
destruct A(0x10e700910)
test
destruct A(0x10e700920)
destruct A(0x10e700928)
destruct A(0x7fff6e21e7f8)
destruct A(0x7fff6e21e800)
现在让我们看看代码:
int main()
{
A o1,
// constructor A(0x7fff6e21e800)
o2;
// constructor A(0x7fff6e21e7f8)
vector <A > O;
O.push_back(o1);
// copy A(0x10e700910: From 0x7fff6e21e800)
cout<<"1"<<endl;
// 1
O.push_back(o2);
// copy A(0x10e700920: From 0x10e700910) // O needs to expand.
// So a new range is created and the old value
// copied from the old range to the new range.
// Now we push o2 into the vector
// copy A(0x10e700928: From 0x7fff6e21e7f8)
// Now the old range has to be destroyed.
// destruct A(0x10e700910)
cout<<"test"<<endl;
// test
return 0;
// Before we exit destroy the old vector (of two items)
// destruct A(0x10e700920)
// destruct A(0x10e700928)
// Now destroy o2 then o1
// destruct A(0x7fff6e21e7f8)
// destruct A(0x7fff6e21e800)
}
intmain()
{
A o1,
//构造函数A(0x7fff6e21e800)
氧气;
//构造函数A(0x7fff6e21e7f8)
向量O;
O.推回(o1);
//复制A(0x10e700910:来自0x7fff6e21e800)
coutYou还需要执行复制构造函数。不理解为什么“O需要扩展。因此创建了一个新范围,并将旧值从旧范围复制到新范围。”第一次创建O
时,它的容量可能为1。推送第一个元素后,它现在已满。但vector将自动展开,当它展开时,它必须将所有元素从旧数据区域复制到新数据区域。如果调用O.reseve()
在开始推送元素之前,此额外副本将消失。
int main()
{
A o1,
// constructor A(0x7fff6e21e800)
o2;
// constructor A(0x7fff6e21e7f8)
vector <A > O;
O.push_back(o1);
// copy A(0x10e700910: From 0x7fff6e21e800)
cout<<"1"<<endl;
// 1
O.push_back(o2);
// copy A(0x10e700920: From 0x10e700910) // O needs to expand.
// So a new range is created and the old value
// copied from the old range to the new range.
// Now we push o2 into the vector
// copy A(0x10e700928: From 0x7fff6e21e7f8)
// Now the old range has to be destroyed.
// destruct A(0x10e700910)
cout<<"test"<<endl;
// test
return 0;
// Before we exit destroy the old vector (of two items)
// destruct A(0x10e700920)
// destruct A(0x10e700928)
// Now destroy o2 then o1
// destruct A(0x7fff6e21e7f8)
// destruct A(0x7fff6e21e800)
}