矢量销毁对象,但不构造它们的替换

vector destroys objects but does not construct their replacements?

本文关键字:替换 对象      更新时间:2023-10-16
#include <iostream>
#include <vector>
using namespace std;
class cMember
{
    public: 
    int id;
    cMember();
    ~cMember();
};
cMember::cMember()
{
    cout<<"member constructorn";
}
cMember::~cMember() 
{
    cout<<"member destructorn";
};
class cDirectory
{
    std::vector<cMember> memberList;
public:
    cDirectory();
    ~cDirectory();
    void Populate();
};

cDirectory::cDirectory()
{
    cout<<"directory constructorn";
}
cDirectory::~cDirectory()
{
    cout<<"directory desctructorn";
}
void cDirectory::Populate()
{
    for(int i = 0; i < 2; i++)
    {
        cout<<"An";
        cMember t;
        memberList.push_back(t);
        cout<<"Bn";
    }
    cout<<"Cn";
}
int main( int argc, const char ** argv )
{
    cDirectory dir;
    dir.Populate();
    exit(0);
}

查看此程序的输出,第二次迭代调用 A 和 B 之间的成员析构函数。我假设这个调用是向量重新分配和重新填充,并在重新分配之前销毁它在其中的成员。

矢量如何破坏对象,但不构建它们的替换?

矢量如何破坏对象,但不构建它们的 更换?

它通过调用对象的复制构造函数而不是用户定义的默认构造函数来构造它们。

也就是说,如果您没有为对象定义一个复制构造函数,编译器将为您隐式定义一个。这里的情况也是如此。当向量的缓冲区被重新分配时,将调用每个对象的复制构造函数,以便将对象复制到新位置。如果按如下方式定义复制构造函数,则可以看到这一点:

class cMember {
public: 
  int id;
  cMember();
  CMember(cMember const&);
  ^^^^^^^^^^^^^^^^^^^^^^^^
  ~cMember();
};
cMember::cMember(cMember const &) {
    cout<<"member copy constructorn";
}

现场演示

因为cMember是静态分配的,所以当函数超出范围时,内存将丢失。如果向量在内存中仍然具有对该点的引用,这将对向量造成问题。因此,std::vector将复制构造该对象。这为向量提供了自己的动态分配副本,即使在函数超出范围后,该副本也会存在于向量中。

我也修改了您的代码以打印this,这是输出:

directory constructor
A
member constructor 0x7fff572e86f8
B
member destructor 0x7fff572e86f8
A
member constructor 0x7fff572e86f8
member destructor 0x7fc1dbc04c80
B
member destructor 0x7fff572e86f8
C

如您所见,在 A 和 B 之间销毁的对象不是由您的函数构造的。相反,它是std::vector使用的副本构造对象。