6

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

这是代码:

#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”消息之后调用析构函数,但在此之前,我不知道。我以为当向量调整大小时,会调用类的构造函数,但是为什么要调用析构函数呢?

4

1 回答 1

17

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

这在 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”案例。但是我没有太多机会说“其他时间”,所以我接受了。

于 2013-01-16T18:14:20.840 回答