2011-06-20 10 views
9

クラス内の演算子=のオーバーロードとコピーコンストラクタの違いは何ですか?operator =のオーバーロードとコピーコンストラクタのオーバーロードの違いは何ですか?

各コンテキストではどのようなコンテキストが使用されていますか。

私は、次のしている場合、私は、意味:

1が使用されている
Person *p1 = new Person("Oscar", "Mederos"); 
Person *p2 = p1; 

を?そして、もう一方が使われたら?

編集:
少しだけを明確にする:

私はすでに我々が明示的にコピーコンストラクタPerson p1(p2)を呼び出す場合、コピーコンストラクタが使用されることを知っています。私が知りたかったのは、それぞれが使用されたときですが、代わりに=演算子を使用して、@ Martinが指摘したとおりです。

答えて

12

あなたのケースでは、ポインタをコピーするときにどちらも使用されません。

Person p1("Oscar", "Mdderos"); 
Person extra; 

コピーコンストラクタ

Person P2(p1);  // A copy is made using the copy constructor 
Person P3 = p2; // Another form of copy construction. 
        // P3 is being-initialized and it uses copy construction here 
        // NOT the assignment operator 

割り当て:

extra = P2;   // An already existing object (extra) 
        // is assigned to. 

代入演算子はCopy and Swap idiumを使用してコピーコンストラクタの用語で書かれたことができることをことを言及する価値があります:

class Person 
{ 
    Person(std::string const& f, std::string const& s); 
    Person(Person const& copy); 

    // Note: Do not use reference here. 
    //  Thus getting you an implicit copy (using the copy constructor) 
    //  and thus you just need to the swap 
    Person& operator=(Person copy) 
    { 
     copy.swap(*this); 
     return *this; 
    } 

    void swap(Person& other) throws() 
    { 
      // Swap members of other and *this; 
    } 
}; 
+0

+1しかし、混乱を避けるために、あなたの答えにはコピーコンストラクタの別の例として 'Person p3 = p1'も含まれているはずです。 –

+0

したがって、コピーコンストラクタは明示的な方法でのみ使用されますか? '='を使わないでください? @OliCharlesworth正確には –

+0

です。私はそれについて疑問に思っている... –

5

コピーコンストラクタはコンストラクタで、オブジェクトを作成します。具体的には、コピーコンストラクタは、他に意味的に同じであるオブジェクトを作成し、それは「コピー」を作るれた既存のオブジェクト:

Person newperson(oldperson); // newperson is a "copy" of oldperson 

割り当てオペレータは全くコンストラクタはないが、既存のオブジェクトに対してのみ呼び出すことができる通常のメンバ関数です。その目的は、別のオブジェクトのセマンティクスをオブジェクトに割り当てることで、割り当て後に2つが意味的に同じになるようにします。通常、代入演算子を「オーバーロード」しているわけではなく、定義しているだけです。

Person p;   // construct new person 
/* dum-dee-doo */ 
p = otherperson; // assign to p the meaning of otherperson, overwriting everything it was before 
        // invokes p.operator=(otherperson) 

それは(==で)オブジェクトと比較することは理にかなっている場合、そのコピーの構築と割り当ての両方が、我々はその後平等を持っているように振る舞うべきだと注意:

Person p1(p2); 
assert(p1 == p2); 

p1 = p3; 
assert(p1 == p3); 

あなたが保証を余儀なくされていませんこれは、あなたのクラスのユーザーは通常、この動作を想定しています。実際には、コンパイラはPerson p1; Person p2(p1);p1 == p2;を必要とすると仮定します。

最後に、脇や他の場所で言ったように、Person p = p2;は文字通りPerson p(p2)(コピー建設)を意味することに注意して、最終的な、そして決してPerson p; p = p2;として。これは構文上の砂糖で、効率を損なうことなく自然に見えるコードを書くことができます(あるいは、あなたのクラスがデフォルトで構成可能でないことさえあるかもしれません)。

+0

あなたの答えをありがとう。私は '='をするときの違いを意味しました。もちろん、 'Person x(y)'を実行するときは、コピーコンストラクタを呼び出しています。分かりますか? –

+0

@オスカー:申し訳ありませんが、私はあなたが「= ''を行うときの違い」という意味を理解していません。質問や不確実な点を言い換えたり、明確にしてください。 –

0

コピーコンストラクタは、引数オブジェクトの内容を使用して新しいオブジェクトを構築します。 オーバーロードされた代入演算子は、既存のオブジェクトの内容を同じクラスの別の既存の オブジェクトに割り当てます。

関連する問題