3

vectorC ++でどのように実装されているかを理解しようとしていました。これを尋ねる以前の質問があったので、それを見て、小さな質問があります。リンクされた質問の実装が正しいと仮定して、次のコードを見てみましょう。

int main(){
    Vector<int> test2 = test_Vector();
    cout << test2[0] << endl;
    return 0;
}


// below is NOT the STL vector object, but the one in the linked question,
// in which the asker tries to implement STL vector himself/herself 
Vector<int> test_Vector(){
    Vector<int> test;
    test.push_back(5);
    return test;
}

私が理解しているように、test Vectorオブジェクトはローカルに作成されるため、test_Vectorメソッドが戻ると、ローカルオブジェクトはスコープ外になり、それによってデストラクタが呼び出されdelete、動的配列が呼び出されます。コードは実際に機能し、5 が出力されるので、私は間違っていると思います。正しい説明は?

4

3 に答える 3

3

あなたは正しいですが、重要なことが1つ欠けています。

を返すのでVector<int>、コピーされていると考える必要があります。これは通常、コピーコンストラクターを呼び出します。コピーコンストラクターは、testの新しいインスタンスにコピーしますVector<int>。コピーコンストラクターは、リンクされた質問に次のように実装されます。

template<class T>
Vector<T>::Vector(const Vector<T> & v)
{
    my_size = v.my_size;
    my_capacity = v.my_capacity;
    buffer = new T[my_size];  
    for (int i = 0; i < my_size; i++)
        buffer[i] = v.buffer[i];  
}

戻り値の最適化により、コピーコンストラクターが呼び出されない場合があることに注意してください(以下のコメントのヘア分割を参照)。多くの場合、コンパイラはコピーを最適化することが許可されており、C ++標準では、この最適化によってプログラムの動作が変わる可能性があるという事実が認められています。

オブジェクトがコピーされるか、RVOが適用されるかにかかわらず、同じ結果になるはずです。通常のオブジェクト指向の慣行に従っている限り、最適化によってオブジェクトが台無しになることはありません。

タイプに関係なく、関数の戻り値が値によって渡される(つまりコピーされる)ことを常に考えてから、コンパイラがおそらくRVOを実行していることを考慮する必要があります。三つのルール(または4、5)を忘れないことが重要です。

于 2013-03-20T23:13:41.090 に答える
1

彼はパブリックコピーコンストラクターを提供しました(技術的には、コピーコンストラクターをプライベートにしませんでした)。そのため、標準のC ++ロジックが起動し、オブジェクトのコピーを作成して返します。新しいオブジェクトはにローカルmainです。コピーコンストラクター内で、新しいメモリがmalloc編集され、データがコピーされます。彼がコピーコンストラクターを提供していなかった場合、無効なメモリにアクセスしていたでしょう(解放されたポインターからメモリにアクセスしようとしました)

于 2013-03-20T23:14:15.803 に答える
1

test返されると、そのコピーコンストラクタが(理論的には)呼び出され、メモリの新しいチャンクが割り当てられ、の内容がコピーされますtest。スタックtest上のオリジナルは(理論的には)破棄され、コピーが割り当てられます。つまり、割り当て演算子が(理論的には)呼び出され、メモリが再度割り当てられ、戻ったときに作成された一時オブジェクトからデータがコピーされます。それから返される一時オブジェクトには、(理論的には)呼び出されるデストラクタがあります。test_Vectortest2test_Vector

ご覧のとおり、コンパイラの最適化がなければ、これは地獄です:)バロック的すぎることを何もしなければ、「理論上」はスキップできます。コンパイラは賢く、状況はこれほど単純です。C ++ 11以降のストーリーの更新については、これを参照してください。

于 2013-03-20T23:14:47.020 に答える