2012-01-14 28 views
5

私はLocationというクラスを持っており、そのメンバー変数にCArrayを追加する必要がありました。この変更により、代入演算子のオーバーロードが必要になりました。C++のオーバーロード代入演算子

変更を加える前にコピーされていたこのクラスタイプのすべての変数をコピーし、個々のメンバ変数を個別にコピーせずにCArrayをコピーする追加コードを追加する方法はありますか?

Location& Location::operator=(const Location &rhs) 
{ 
    // Only do assignment if RHS is a different object from this. 
    if (this != &rhs) 
    { 
     //Copy CArray 
     m_LocationsToSkip.Copy(rhs.m_LocationsToSkip); 

     //Copy rest of member variables 
     //I'd prefer not to do the following 
     var1 = rhs.var1; 
     var2 = rhs.var2; 
     //etc 
    } 

    return *this; 
} 
+0

ですから、実際には、コンパイラが生成した代入演算子を呼び出すようにしたいですか? 'CArray'に代入演算子がありますか? –

+0

コピーコンストラクタはありますが、代入演算子はありません。私はCArrayメンバ変数を追加したのでコンパイラが生成した代入演算子を呼び出すことができるかどうかはわかりません。 –

+2

いいえ、コンパイラが生成したコンパイラを呼び出すことはできません。なぜなら、コンパイラ生成時に生成されないからです。(CArrayメンバを追加したためではなく、コンパイラが生成したクラスだけが、 1つは存在しないためCArray用です)。私はこれを行う方法がないと思います。 –

答えて

4

ありがとうございます。 operator=自体をオーバーロードするタイプを使用してください。そのため、代わりにそのクラスを含むクラスで行う必要はありません。 MFCコードを書くときでも、私はまだMFCのコレクションと文字列クラスの代わりにstd::vectorstd::stringなどを使用します。時々あなたはCStringを使用してかなり詰まっていますが、最後にstd::vectorの代わりにCArrayを使用したときは思い出せません。

+0

これは私が必要とするものに最も近いと思います。残念ながら、アプリケーションの残りの部分はmfcコンテナを使用しており、stlコンテナを使用するようにこれを変更するのは嫌です。しかしこれは良い解決策です。ありがとう。 –

0

いいえ、できません。 これを行う最善の方法は、実際のコードを生成するスクリプトを使用することです。

0

これは、通常、「コピーとスワップイディオム」と呼ばれるもので行われます。メンバ値と、最も重要なことには外部データへのポインタを交換するコピーコンストラクタとswap()メソッドを実装します。これで、割り当て担当者は次のようになります。

C& C::operator=(const C& c) { 
    C tmp(c); 
    this->swap(tmp); 
    return *this; 
} 

これで自己割り当てのガードは必要ありません。

+0

しかし、あなたは 'swap'実装のすべてのメンバーを列挙しなければなりません。これは問題を動かすだけで解決しません。 –

+0

まあ、私はここに問題が表示されません。値のメンバーが多すぎますか?構造体にパッケージ化して、タイピングが少ない場合は代入を行います。 –

2

はい。私が通常行うことは、コピー可能でないものを除いて、クラス内のメンバー構造体にすべてを入れることです。このように:

class Location 
{ 
    struct Members 
    { 
     int var1, var2; 
    }; 

    Members m; 
    CArray m_LocationsToSkip; 

public: 
    Location& operator=(Location const& rhs); 
}; 

Location& Location::operator=(const Location &rhs) 
{ 
    // Only do assignment if RHS is a different object from this. 
    if (this != &rhs) 
    { 
     //Copy CArray 
     m_LocationsToSkip.Copy(rhs.m_LocationsToSkip); 

     //Copy rest of member variables 
     m = rhs.m; //will use Members automatically generated operator= 
        //which should do the correct thing because you only put 
        //normally copyable members in m 
    } 

    return *this; 
} 

は、私が最初にここにこのことについて投稿:https://stackoverflow.com/questions/469696/what-is-your-most-useful-c-c-utility/1609496#1609496

+0

これはまともな解決策のようですが、これをサポートするためにアプリケーションの残りの部分でかなりのリファクタリングが必要になります。 –

+0

@Cole W:どうですか?メンバーは公開され、アプリケーションのどこでも使用されますか?その場合、別の方法として、リソース管理クラスを作成してCArrayをenglobすることができます(例とは多少異なります)。リファクタリングが必要なメンバーが1人しかいない可能性があります)。私は構造体でその例を使用しました。なぜなら、これは私のコードで必要だったものです(ポインタではなく配列であり、スマートポインタは必要なものではありませんでした)が、あなたのケースでは、CArrayより良い選択となる。 – n1ckp

関連する問題