7

私はプログラムをデバッグしようとしていますが、そうすることで、C ++ベクトルのpush_back()関数の理解にぶつかりました。

私の主張を説明するために、私は次の短いプログラムを書きました。

#include <iostream>
#include <vector>
#include <cstdlib>

using std::cout;
using std::endl;
using std::vector;

class Test {
private:
  int mTestMember;
public:
  Test(int val);
  Test(const Test&);

  int GetValue() const;
};

Test::Test(int val)
{
  cout << "Constructor\n";
  mTestMember = val;
}

Test::Test(const Test& test)
{
  cout << "Copy Constructor\n";
  mTestMember = test.mTestMember;
  cout << "mTestMember: " << mTestMember << endl;
}

int main(){

  vector<Test> tests;
  tests.push_back(Test(int(5)));
  cout<< endl;
  tests.push_back(Test(int(6)));
  cout << endl;
  tests.push_back(Test(int(7)));

  return(0);
}

コンパイルして実行すると、次の出力が得られます。

Constructor
Copy Constructor
mTestMember: 5

Constructor
Copy Constructor
mTestMember: 6
Copy Constructor
mTestMember: 5

Constructor
Copy Constructor
mTestMember: 7
Copy Constructor
mTestMember: 5
Copy Constructor
mTestMember: 6

push_back()関数のプロセスで、push_back()関数(私がすでに知っている)に引数として渡されたオブジェクトのコピーが実行され、その後、残りの要素が実行されたように見えます。既存のものに存在するものも、正面から新しいベクトルにコピーされます。

プロセスの理解は正しいですか?

4

1 に答える 1

11

std::vectorその要素を配列に格納します。配列のサイズは常に固定されているため、に要素を追加し続けるとstd::vector、その基になる配列は最終的にいっぱいになります。配列がいっぱいで、別の要素を追加する場合(push_backまたは、新しい要素を追加する別のメンバー関数を介して)、次のことを行う必要があります。

  1. 新しい、より大きなアレイを作成し、
  2. 要素を古い配列から新しい配列にコピーまたは移動(*)し、
  3. 新しい要素を新しい配列に挿入し、
  4. 古いアレイを破棄します

このプロセスは再割り当てと呼ばれます。の正しい実装でstd::vectorは、配列のサイズを指数関数的に変更する必要があります。Visual C ++のstd::vector実装では、1.5倍の成長係数を使用します。他の実装では、異なる成長因子を使用する場合があります。


(*)C ++ 11は、オブジェクトの移動のサポートを追加します。

于 2012-07-17T23:26:02.390 に答える