1
class A
{
    public:
        A():a(0)
        {}
        A(int x):a(x)
        {
            cout<<"convert"<<endl;
        }
        A(const A& rhs):a(rhs.a)
        {
            cout<<"copy: "<<a<<endl;
        }
        void print()
        {
            cout<<a<<endl;
        }
        void Set(int x)
        {
            a=x;

        }
    private:
        int a;
};

int main()
{
    vector<A>vec2(2,A(100));
    cout<<"the size: "<<vec2.size()<<"  the capacity: "<<vec2.capacity()<<endl;
    vec2.push_back(17);
    for(int i=0; i<vec2.capacity();i++)
    {
        vec2[i].print();
    }
    cout<<"the size: "<<vec2.size()<<"  the capacity: "<<vec2.capacity()<<endl;
}
変換
コピー:100
コピー:100
サイズ:2容量:2
変換
コピー:17
コピー:100
コピー:100
100
100
17
0

なぜこれが起こったのか

copy: 17
copy: 100
copy: 100     

容量は4ではなく5のようです。プッシュしたい要素がベクトルにプッシュされた後、容量が増加しました。間違っているはずです。誰かに詳細を教えてもらえますか?

4

3 に答える 3

3

ベクトルのサイズと容量の違いを理解していれば、容量を増やす必要がある場合は、ベクトル全体をメモリ内の別の場所に移動する必要があることに気付くでしょう。

コピー コンストラクターの呼び出しは、ベクター要素が古いベクターから新しいベクターに「移動」されるときに発生します。デバッグを伴うデストラクタを追加すると、より理にかなっているかもしれません。

また...

for(int i=0; i<vec2.capacity();i++)

... いい考えではありません。有効なベクター データの末尾を超えてアクセスしています。

于 2012-10-09T20:49:17.600 に答える
2

サイズと容量の呼び出しの直前vec2.push_back(17)(アプリケーションによって出力される)は両方とも2です。この時点で、17はAオブジェクトに変換され、関数に渡されpush_backます。内部的にstd::vectorは、バッファをより大きな容量に拡張し(これにより、A値100の2つのコピーが発生します)、引数がpush_back新しく割り当てられたバッファにコピーされます。実装では、新しく挿入された要素が既存の要素の前にコピーされます。

最後に、からを繰り返すと、未定義の動作が発生します0。ベクトルfromからまでvec2.capacity()の要素を合法的に反復することのみが許可されています。プログラムの出力は、実装でバッファーが(4つの要素が出力される)に成長したことを示しています。0vec2.size()capacity()==4

于 2012-10-09T20:46:42.313 に答える
1

容量を使用する for ループは使用しないでください。通常、容量は 2 倍になります。これは、新しい要素を挿入するときにメモリが破棄されるのを防ぐためです。

初期容量が 2 の場合、3 番目の要素を追加すると 2 倍の 4 になります。5 番目の要素を追加すると、新しい容量は 8 になります。

于 2012-10-09T20:44:51.953 に答える