5

土曜日に私は試験を受け、過去の論文を調べていますが、C++コードによる質問に遭遇しました。

class Car {
     char *LicencePlate;
     int age;
public:
     Car(const Car &); //this declaration
     ~Car();
}

5行目の宣言の目的は何ですか?一般に、この性質の宣言の実装はどのような機能を提供する必要がありますか?Car.cpp提供された情報が与えられた場合にファイルに表示されるように、5行目に宣言の実装に必要なコードを記述します。

4

5 に答える 5

9

これを見てみましょう。

名前からわかるように、それはコンストラクターです。同じ型のオブジェクトへの参照をパラメーターとして受け取るため、コピーコンストラクター(C ++の命名法)です。

ご存知のように(またはそうでない場合)、コピーコンストラクターがない場合は、コンパイラーがコピーコンストラクターを生成します。コンパイラによって生成されたコピーコンストラクタは、浅いコピーを実行します。

独自に実装する理由:

class Car {
     char *LicencePlate;
public:
     Car(char* plate, int size)
     {
        LicencePlate = new char[size];
        strcpy(LicencePlate, plate);
     }
     ~Car()
     {
        delete[] LicencePlate;
     }
};

説明をわかりやすくするために、クラスを少し変更しました。あなたのクラスは今メモリを管理しています。にメモリを割り当てますLicencePlate。これは、コピーコンストラクターがないシナリオです。あなたがするように言う:

Car a("abc",3);

コンパイラによって生成されたコピーコンストラクタは、次のように呼び出されます。

Car b(a);

ただし、これは浅いコピーのみを行うことを忘れないでください。だから、実際には、a.LicencePlate == b.LicencePlate何か問題がありますか?

スコープ外にaなると、デストラクタが呼び出さa.LicencePlateれて削除されます。bただし、スコープ外になると、デストラクタが同じメモリを削除しようとするため、未定義の動作が発生しbます(浅いコピーが作成されたため、2つのポインタが同じメモリを指していることに注意してください)。

これを回避するには、独自のコピーコンストラクターを定義します。

class Car {
     char *LicencePlate;
     int sz;
public:
     Car(char* plate, int size)
     {
        LicencePlate = new char[size+1]();
        strcpy(LicencePlate, plate);
        sz = size;
     }
     Car(const Car& other)
     {
        LicencePlate = new char[other.sz+1]();
        sz = other.sz;
        strcpy(LicencePlate, other.LicencePlate);
     }
     ~Car()
     {
        delete[] LicencePlate;
     }
};

三つのルールは、代入演算子を実装する必要があることを意味します(すでにコピーコンストラクタとデストラクタがあります)。この背後にある動機は同じですが、初期化する代わりに割り当てるときに問題が再現されるだけです。

Car a("abc",3);
Car b;
b = a; //assignment - operator= is called

今、私たちは安全です。b、コピーすると、ナンバープレートを保持するために新しいメモリが割り当てられるため、二重削除は発生しません。

ポイントを示すためにコードを変更しましたが、それでも自分でロジックを配置する必要があります。

于 2012-05-23T21:33:58.880 に答える
8

これはコピーコンストラクターであり、パラメーターとして指定されたオブジェクトの正確なコピーを作成することを目的としています。

それを行う最善の方法を決めるのはあなたに任せます。

于 2012-05-23T21:15:55.480 に答える
2

これはコピーコンストラクター宣言です。定数への参照を取りますCar。つまり、渡された値を読み取ることはできますが、(危険なキャストなしで)書き込むことはできません。これは、元のオブジェクトをコピーして新しいオブジェクトを作成するための標準的な方法です。おそらくstrdup、実装の一部としてを実行することをお勧めします。

于 2012-05-23T21:16:37.770 に答える
0

この宣言は、コピーコンストラクターと呼ばれます。通常、コピーコンストラクターは、特定のインスタンスの新しいインスタンスをクラスに構築するために使用されます。

署名:

Car(const Car &)

「const」は、渡されたインスタンスをメソッドで変更できないことを意味します。「&」は、インスタンスが参照によってメソッドに渡されることを意味します。「&」(値渡し)のないクラスのインスタンスを渡すと、コピーコンストラクターを使用してクラスの新しいインスタンスが作成されます。コピーコンストラクターの宣言の場合、値の受け渡しは自己敗北するだけでなく、スタックオーバーフローが発生するまでコピーコンストラクターが再帰的に呼び出されます。

cppファイルに入るコードは、渡されたインスタンスの許容可能なコピーを作成する必要があります。ユーザーのシナリオに基づいて意味のある方法で許容可能です。

于 2012-05-23T21:24:29.020 に答える
-3

私はあなたが5行目を意味すると仮定します

Car(const Car &);

引数が別のCarオブジェクトへの参照のみであるコンストラクターです。コンストラクターが特定の車を変更してはならないことを示すために、constとしてマークされています。これは参照であるため、作成中の同じオブジェクトへの参照が何らかの理由でないことを確認する必要があります。

if (this==car){
  return;
}

またはそのようなもの。

于 2012-05-23T21:18:05.403 に答える