c++ - 为什么在初始化和调整对象 vector 大小时调用析构函数?

标签 c++ vector

我的程序中发生了一些事情,我无法确定它是否应该发生。如果是,我不明白为什么..

代码如下:

#include <iostream>
#include <vector>

using namespace std;

class A{
  public:
    A();
    ~A();
};

A::A(){
  cout << "creating" << endl;
}

A::~A(){
  cout << "deleting" << endl;
}

int main(void){
  vector<vector<A > > vec;

  vec.resize(5);
  for(int i = 0; i < 5; ++i){
    vec[i].resize(5);
  }

  cout << "END" << endl;

  return 0;
}

这是输出:

creating
deleting
creating
deleting
creating
deleting
creating
deleting
creating
deleting
END
deleting
deleting
[..more deleting here]

我理解为什么在“END”消息之后调用析构函数,但之前我不理解。我还以为vector resize的时候会调用类的构造函数,为什么是析构函数呢?

最佳答案

在 C++03 中 vector<A>::resize()有一个默认参数,默认值为A() .被破坏的是这个暂时的。 vector 的元素是从它复制构造的。

这在 C++11 中是“固定的”,其中有两个重载 resize .一个只有一个参数,并值初始化任何其他元素。另一个有两个参数,并根据提供的值复制初始化每个附加元素。在 C++11 中,此程序具有以下行为:

creating
creating
creating
<repeated for a total of 25 "creating"s>
creating
creating
creating
END
deleting
deleting
deleting
<repeated for a total of 25 "deleting"s>
deleting
deleting
deleting

在 C++03 中,如果 A 的实例构建起来非常昂贵,因此值得将数量最小化,然后您可以将它从 5 个无参数 + 25 个复制结构减少到 1 个无参数和 25 个复制结构,如下所示:

A default_value;
for (int i = 0; i < 5; ++i) {
   // same end result as vec[i].resize(5)
   if (vec[i].size() >= 5) {
       vec[i].erase(vec.begin() + 5, vec.end());
   } else while(vec[i].size() < 5) {
       vec[i].push_back(default_value);
   }
}

您可能会稍微不同地编写它,显然对于您的示例代码,您不需要“if”大小写。但我没有太多机会说“其他时候”,所以我接受了。

关于c++ - 为什么在初始化和调整对象 vector 大小时调用析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14364937/

相关文章:

vector - 在 Rust 中连接向量的最佳方法是什么?

c++ - 代码执行 : How to create a multiple dimensional array manually?

c++ - 如何使用列表初始化对聚合类型进行值初始化

C++ vector 操作

r - 使用向量将多个 csv 文件读入到 r

arrays - 如何使用函数初始化数组?

c++ - 有没有办法通过zeromq pub sub C++发送字符串以外的数据类型?

c++ - 如何通过透明代理实现SSL隧道?

c++ - 如何使用 Rcpp 库将 C++ 中包含 double 值的 vector vector 转换为 R 中的矩阵?

r - 摆脱附加字符向量的循环