0

https://stackoverflow.com/a/3278636/462608

Class::Class( const char* str )
{
    stored = new char[srtlen( str ) + 1 ];
    strcpy( stored, str );
}

この場合、保存されたメンバーのメンバーごとのコピーはバッファーを複製しません (ポインターのみがコピーされます)

しかし、ここでメモリはによって割り当てられていnewます。それでは、バッファ全体ではなくポインタのみがコピーされると言われているのはなぜですか?

4

3 に答える 3

4

あなたのクラスClassには、という名前のポインタがありますstored。のインスタンスClassがコピーされたとき、たとえば

Class a("hello");
Class b = a;  // Copying a

次に、ポインターstoredがコピーされるため、同じポインターを持つ2つのオブジェクトがあります。次にdelete、1 つのオブジェクトのポインターの場合、他のオブジェクトにはまだ未割り当てのメモリを指すポインターがあります。

そのため、コピー コンストラクターを作成する必要があります。

Class(const Class& other)
{
    stored = new char[strlen(other.stored) + 1];
    strcpy(stored, other.stored);
}

上記のコピー コンストラクターがある場合、最初のコード スニペットのようにコピーが行われると、新しい文字列が割り当てられ、他のインスタンスのコンテンツがコピーされます。もちろん、2 つのオブジェクト インスタンス間で代入するときに使用するコピー代入演算子も必要です。

Class& operator=(const Class& other);
于 2013-09-04T06:53:33.823 に答える
1

あなたのクラスには、 という名前のポインタであるメンバーがありますstored。のインスタンスClassがコピーされる場合:

Class foo( "str" );
Class bar( foo );   // Copy

デフォルトのコピーコンストラクターを使用すると、クラスのメンバーがコピーされます。その場合、storedそのコンテンツではなく、ポインターである人がコピーされます。

そのため、ここでコピー コンストラクターoperator=or コピー代入演算子を次のように再定義する必要があります。

Class::Class( const Class& another )
{
    stored = new char[strlen(another.stored) + 1];
    strcpy( stored, another.stored );
 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Copy the buffer
}

void Class::operator = ( const Class& another )
{
    char* temp = new char[strlen(another.stored) + 1];
    strcpy( temp, another.stored);
 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Copy the buffer
    delete[] stored;
    stored = temp;
}

そうしないと、最初のインスタンス (たとえばa) が破棄されたときに、 のメンバーにアクセスしようとすると、未定義の動作が発生します。storedb

于 2013-09-04T06:59:10.637 に答える