4

あなたが私を助けることができるかどうか疑問に思っていました。ここでOperator = C++のConst変数でオーバーロード

は私の.hです:

Class Doctor { 
    const string name; 
    public: 
     Doctor(); 
     Doctor(string name); 
     Doctor & Doctor::operator=(const Doctor &doc); 
} 

と私のメイン:

int main(){ 
    Doctor d1 = Doctor("peter"); 
    Doctor d2 = Doctor(); 
    d2 = d1; 
} 

私は演算子=の機能をしたいです。誰でも助けてくれますか? Doctorのconstメンバーに注目してください。

*********** EDIT:********* 私の主な問題は、別のクラスに、Pacientのような医者の属性を持たせたいということです。医師。しかし私は私の医者を変えることができるようにしたい。私は医者Aを見ていますが、私は医者Bを見たいと思っています。それは私の他のクラス(Pacient)のsetDoctor関数を使って行います。コードを実行していた場合、私は次のように言っています。

class Patient{ 
    Doctor &d; 
}; 

そしてポインタを変更します。しかし、私は先生の一人によって作られた基本コードを使用していますし、それは、クラスは次のように定義されています:

class Patient{ 
    Doctor d; 
} 

しかし、私はこれが原因で、私はどちらかになるだろうPatientクラスでsetDoctor()で行うことは不可能だと思いますvarable自体をコピーまたは変更します。最初のものは違いがなく、2番目のものはconstのために不可能です。私は正しい?

+0

明らかに変更が必要な場合は、なぜそれをconstにしていますか? –

+0

初期化されていません...私はよく覚えていませんが、一度初期化すると変更できないと思います。 – jasonco

+0

コピーコンストラクタではない理由はありますか? –

答えて

7

あなたはほぼそこにあります。いくつかの注目点:

  • 名前はconstであるべきではありません。 constは変更できません。これはまさに代入演算子で必要なものです。

  • C++キーワードは、あなたのコードがそれを持っているとして、マイケルバリが指摘したよう

  • (それはあなたがコンパイルエラーをあげる)classないClassです:「それはクラスが単純に他の含まれている場合にかかわらず、それは注意すべきです(この場合単純な文字列メンバのように)割り当てを正しくサポートしているクラスでは、暗黙のコンパイラ生成の演算子=()はうまく動作します。ここでは、あなたの場合、唯一のメンバーstringは、適切なop=を持っています。明示的に定義することは冗長です。

  • ミーの解がほとんどあります。話していないのは、自己割り当てだけです。 FAQ 12を読んでください。

  • 割り当てはBig Threeのメンバー関数FAQ 27.10です。調べる。これは、copy ctor、op =またはdtorのいずれかを実装する要件は、通常、他の2つを実装する必要があることを意味します。修正されたコードサンプルは、このようなものでなければなりません

class Doctor { 
    string name; 
    public: 
    Doctor& operator=(Doctor const& o) { 
     if (&o != this) name = o.name; 
     return *this; 
    } 
    // ... 
}; 
+0

クラスに単純に割り当てをサポートしている他のクラス(この場合は単純な文字列メンバ)が含まれていれば、暗黙のコンパイラ生成演算子=()は正常に動作します。 –

+0

@マイケル:うん、私はこれを加えておかなければならない。私は自分の投稿を編集します。 – dirkgently

+0

@マイケル:const問題は、 "Doctor = NULL; Doctor d2 = Doctor(); d1 = d2;" ? –

0

あなたの名前はconstなので、コンストラクタを通して "変更"する唯一の方法です。 =演算子を使用する場合は、文字列を "アンコンストレイン"する必要があります。

Doctor(const &Doctor d); 

を...、それを実装します:あなたは、文字列「unconst」にしたくない場合は、コピーコンストラクタを作成することにより、多少同じ動作を得ることができ

..

Doctor::Doctor(const &Doctor d) 
    : name(d.name) 
{ 
//Im pretty sure you have access to private attributes here 
// My C+ is a bit rusty :) If not, make a const string getName() method 
} 
+0

Doctor :: Doctor(const Doctor&d):name(d.name){} –

+0

Aaahはい、私は何かを忘れていたことを知っていました:)病気の編集私の答え – cwap

+0

dribeasの修正に追加するには、コンストラクタ内の文字列を変更することもできません。文字列はconstです。文字列を変更できる唯一のものは文字列のコンストラクタです。 –

2

宣言はDoctor &operator=(const Doctor &other);(すなわち、削除医者です:あなたはのconstネスO < >を削除するためにはconst_castを使用する必要があるだろう、そこから:)

fメンバ変数を動作させる。あなたが選んだ道に虚栄心だけがあることに注意してください。

メンバ宣言からconstを削除し、必要に応じてメンバー関数constをオブジェクトに影響を与えないことを示すためにconstにすることをお勧めします。 (たとえば、アクセサメンバー関数を使用している場合、const:string getName() const { return m_name; }

+0

確かにconst_cast <>は悪魔によって作られています:)それが私の答えに追加しなかった理由です。 – cwap

1

として多くの人が先に言った、メンバーは「CONST」ですそれはその作成時に初期化する必要があり、それがないことを示しています変更するはずです。 そのような場合に代入演算子を書く必要があり、そのメンバー変数の代入をスキップできない場合は、それを '変更可能'にしてください。

覚えておいてください。 C++標準から、 "本来宣言されたconst変数のキャストを外すことは未定義の動作です。"

HTH、 アブヘイ

2

それは安全な例外があるように正しく割り当てコンストラクタを定義する標準的な方法は、コピーコンストラクタの用語で、それを定義することです。

class Doctor 
{ 
    public: 
     Doctor& operator=(Doctor const& rhs) 
     { 
      if (this != &rhs) 
      { 
       Doctor tmp(rhs); // Use copy constructor here 
       this->swap(tmp); // Now Swap 
      } 
      return *this; 
     } 
     void swap(Doctor& rhs) throws() 
     { 
      std::swap(.....); // swap each member variable. 
     } 
}; 

このようにすると、例外的に安全になります。
スワップをノースローにする必要があることに注意してください。これはSTLオブジェクトを使用している場合には比較的単純です。ブーストやすべての良いライブラリと同じようにスロースワップを定義しています。スイートに従う)。

これが間違っている場合は、コピーコンストラクタの使用に間違いが生じます。現時点では、コピーを一時的なものにするのと同じように、自分のオブジェクトを変更していません。したがって、あなたのオブジェクトはまだ変更されていないので、優れた例外安全性を提供しています。

0

あなたはまた、&をCONSTする戻り値の型を変更したい:現実には、彼らが無効である間、constのは、以下のコンパイルなどのコードを作る省略

const Doctor& operator=(const Doctor &doc); 

ある
(A = B) = C; 

ではなく、(これはおそらく意図したものです)

A = B = C; 
関連する問題