2

コピー コンストラクターについて質問があります。これらの例をインターネットで見ます。最初のものは、student2で何かを変更すると、同じフィールドがstudent1でも変更される場合、コピーコンストラクターなしで言います。しかし、2 番目の例では、コピー コンストラクターがあるため、student2 の変更は Student1 に影響しません。これがどのように起こったのか理解できませんでした。実際にコピーコンストラクターはここで何をしますか? (悪い英語でごめんなさい)(すべての回答に感謝します:))

class MITStudent {
public:
    int studentID;
    char *name;
    MITStudent() {
        studentID = 0;
        name = "";
}

};
   int main() {
      MITStudent student1;
      student1.studentID = 98;
      char n[] = "foo";
      student1.name = n;
      MITStudent student2 = student1;
      student2.name[0] = 'b';
      cout << student1.name; // boo
 }

二つ目

class MITStudent {
public:
    int studentID;
    char *name;
    MITStudent() {
        studentID = 0;
        name = "";
    }

    MITStudent(MITStudent &o) {
        name = my_strdup(o.name);
        studentID = o.studentID;
    }

};
int main() {
   MITStudent student1;
   student1.studentID = 98;
   char n[] = "foo";
   student1.name = n;
   MITStudent student2 = student1;
   student2.name[0] = 'b';
   cout << student1.name; // foo

}

4

5 に答える 5

3

独自のコピー コンストラクターを指定しない場合、既定のコピー コンストラクターが自動的に生成されます。
クラスのすべてのメンバーを値で新しいクラスにコピーするだけです。

この問題は通常、クラス メンバとしてポインタがある場合に発生します。
デフォルトのコピーコンストラクターは、ポインターが保持しているアドレスをコピーするだけです。
これは、元のクラスとコピーされたクラスの両方が同じオブジェクトを指していることを意味します。

それはまさにchar*「文字列」を使用した例で起こることです...

ところで、経験則として..メンバーとしてポインターを持つクラスがある場合は、カスタムコピーコンストラクターを作成します。

于 2012-07-28T15:57:26.557 に答える
0

典型的なケースでは、デフォルトのコピー コンストラクターを使用すると、状況は図の左側のようになります。. これを回避するためにコピー コンストラクターが実装されており、右側に示すようなシナリオがあります。

ただし、通常、これはポインター メンバーで発生します。したがって、それらをできるだけ避けてください。次の場合にのみ使用してください。 1. コンストラクターよりも後の段階でのみメンバーを作成できる 2. メンバーを破棄して再作成したい 3. メンバーをオブジェクトより長生きさせたい。

あなたの場合、上記のシナリオのいずれにも属していないようです。この場合、nice 文字列オブジェクトを安全に使用でき、ダングリング ポインターについて心配する必要はありません。

于 2012-07-28T16:14:33.570 に答える
0

作成しない場合は、コピー コンストラクターが自動的に生成されます。自動生成されたコピー コンストラクターは、名前自体ではなく、ポインターを名前にコピーするだけです。独自のコンストラクターを作成すると、ポインターだけでなく、名前全体を手動でコピーできます。

ただし、実際のコードでは、char* の代わりに std::string のようなものを使用する必要があります。この方法では、自動生成されたコピー コンストラクターが目的の処理を実行するので、独自に作成する必要はありません。

于 2012-07-28T15:54:02.803 に答える
0

存在しないMITStudent(MITStudent &o)場合は、すべてのフィールドの値をコピーするだけです。したがって、ポインタ フィールドがある場合、両方のフィールドに同じアドレスが含まれます。

于 2012-07-28T15:57:34.560 に答える
0

最初の例では、コピー コンストラクターはコンパイラーによって暗黙的に作成されます。

基本的には次のようになります。

MITStudent(const MITStudent &o) {
    name = o.name;
    studentID = o.studentID;
}

ポインタをコピーするだけnameです。

2 番目の例では、コピー コンストラクターが明示的に作成され、name指しているデータをコピーします。このように、nameinstudent2はコピーされたデータを指しています。

于 2012-07-28T15:58:14.787 に答える