C++ 在std::vector中的push_返回过程中有趣的额外销毁调用

C++ 在std::vector中的push_返回过程中有趣的额外销毁调用,c++,c++11,C++,C++11,我发现下面代码的输出非常有趣 class Name { string _name; public: Name(const string& name) : _name(name) { cout << "ctor of " << _name << endl; } ~Name(){ cout << "dtor of " << _name << endl; } }; int

我发现下面代码的输出非常有趣

class Name
{
  string _name;
public:
  Name(const string& name) : _name(name) { cout << "ctor of " << _name << endl; }
  ~Name(){ cout << "dtor of " << _name << endl; }
};
int main() {

  vector<Name> list;
  cout << "------------------START push_back" << endl;
  list.push_back(Name(string("A")));
  cout << "------------------push_back(A) performed..." << endl;
  list.push_back(Name(string("B")));
  cout << "------------------push_back(B) performed..." << endl;
  list.push_back(Name(string("C")));
  cout << "------------------push_back(C) performed..." << endl;
  cout << "------------------END push_back" << endl;

  return 0;
}
有人能解释一下下面的输出中显示的额外析构函数调用吗

------------------START push_back
ctor of A
dtor of A
------------------push_back(A) performed...
ctor of B
dtor of A(???)
dtor of B
------------------push_back(B) performed...
ctor of C
dtor of A(???)
dtor of B(???)
dtor of C
------------------push_back(C) performed...
------------------END push_back
dtor of A
dtor of B
dtor of C
------------------START emplace_back
ctor of A
------------------emplace_back(A) performed...
ctor of B
------------------emplace_back(B) performed...
ctor of C
------------------emplace_back(C) performed...
------------------END emplace_back()
dtor of A
dtor of B
dtor of C
内存分配的大小不能更改。由于为数组分配的内存不能更改,因此数组的大小相应地不能更改

向量的元素存储在单个分配内存块中,形成一个数组。如果内存块不能改变大小,那么如何向向量添加元素呢?嗯,我们可以做的是分配一个较大的内存块,然后将元素从较小的块复制(移动)到较大的块,然后销毁旧块中的旧元素,最后释放旧块。这就是向量在为其元素分配的内存块(称为容量)中添加的元素过多时所做的

有人能解释一下下面的输出中显示的额外析构函数调用吗

------------------START push_back
ctor of A
dtor of A
------------------push_back(A) performed...
ctor of B
dtor of A(???)
dtor of B
------------------push_back(B) performed...
ctor of C
dtor of A(???)
dtor of B(???)
dtor of C
------------------push_back(C) performed...
------------------END push_back
dtor of A
dtor of B
dtor of C
------------------START emplace_back
ctor of A
------------------emplace_back(A) performed...
ctor of B
------------------emplace_back(B) performed...
ctor of C
------------------emplace_back(C) performed...
------------------END emplace_back()
dtor of A
dtor of B
dtor of C
这些是向量重新分配时旧内存中被破坏的元素

如果您想知道为什么在新内存中构建对象时没有输出,那是因为类的move构造函数没有生成输出

若您想知道为什么在每个添加的元素之后并没有额外的破坏,那个是因为vector在增长时并不仅仅为单个元素分配内存。相反,它将容量乘以某个系数(通常使用2或1.5的系数)。这使得在初始不知道元素的最终数量时,插入大量元素的渐进复杂性更好

有人能解释一下下面的输出中显示的额外析构函数调用吗

------------------START push_back
ctor of A
dtor of A
------------------push_back(A) performed...
ctor of B
dtor of A(???)
dtor of B
------------------push_back(B) performed...
ctor of C
dtor of A(???)
dtor of B(???)
dtor of C
------------------push_back(C) performed...
------------------END push_back
dtor of A
dtor of B
dtor of C
------------------START emplace_back
ctor of A
------------------emplace_back(A) performed...
ctor of B
------------------emplace_back(B) performed...
ctor of C
------------------emplace_back(C) performed...
------------------END emplace_back()
dtor of A
dtor of B
dtor of C
内存分配的大小不能更改。由于为数组分配的内存不能更改,因此数组的大小相应地不能更改

向量的元素存储在单个分配内存块中,形成一个数组。如果内存块不能改变大小,那么如何向向量添加元素呢?嗯,我们可以做的是分配一个较大的内存块,然后将元素从较小的块复制(移动)到较大的块,然后销毁旧块中的旧元素,最后释放旧块。这就是向量在为其元素分配的内存块(称为容量)中添加的元素过多时所做的

有人能解释一下下面的输出中显示的额外析构函数调用吗

------------------START push_back
ctor of A
dtor of A
------------------push_back(A) performed...
ctor of B
dtor of A(???)
dtor of B
------------------push_back(B) performed...
ctor of C
dtor of A(???)
dtor of B(???)
dtor of C
------------------push_back(C) performed...
------------------END push_back
dtor of A
dtor of B
dtor of C
------------------START emplace_back
ctor of A
------------------emplace_back(A) performed...
ctor of B
------------------emplace_back(B) performed...
ctor of C
------------------emplace_back(C) performed...
------------------END emplace_back()
dtor of A
dtor of B
dtor of C
这些是向量重新分配时旧内存中被破坏的元素

如果您想知道为什么在新内存中构建对象时没有输出,那是因为类的move构造函数没有生成输出


若您想知道为什么在每个添加的元素之后并没有额外的破坏,那个是因为vector在增长时并不仅仅为单个元素分配内存。相反,它将容量乘以某个系数(通常使用2或1.5的系数)。当最终元素数最初未知时,这会导致插入大量元素的渐进复杂性更好。

std::vector是一个动态数组。

每当没有足够的内存来存储元素时,std::vector就会尝试重新分配更大的内存块来存储更多的元素。之后,它需要将元素复制(移动)到其他块中,隐式地调用前面元素的DTOR

要了解正在发生的事情,请尝试扩展您的课程:

类名
{
字符串\u名称;
公众:

Name(const string&Name):\u Name(Name){coutstd::vector是一个动态数组。

每次没有足够的内存分配来存储元素时,std::vector都会尝试重新分配更大的内存块来存储更多元素。之后,它需要将元素复制(移动)到其他块中,隐式调用以前元素的DTOR

要了解正在发生的事情,请尝试扩展您的课程:

类名
{
字符串\u名称;
公众:

名称(常量字符串和名称):\u名称(名称){cout Instrument the move constructor并确保它被标记为
noexcept
。您应该将
this
的值与
\u name
一起打印。这样可以更好地说明正在发生的情况。您会看到
this
是与另一个对象关联的值。Instrument the move constructuctor并确保它标记为
noexcept
。您应该将
的值连同
\u name
一起打印出来。这样可以更好地说明正在发生的事情。您会看到
是与另一个对象关联的值。@RichardCriten我想他们理解考虑到eir对
push_back
情况下额外破坏的评论,但我还是添加了一个解释。@RichardCriten我想他们理解,考虑到他们对
push_back
情况下额外破坏的评论,但我还是添加了一个解释。