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で「修正」されており、の2つのオーバーロードがありresizeます。1つには単一のパラメーターがあり、追加の要素を値で初期化します。もう1つには2つのパラメーターがあり、指定された値から追加の各要素をコピー初期化します。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つのno-args-+25のcopy-constructionから1つのno-arg-と25のcopy-に削ることができます。次のような構造:

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 に答える