2009-03-17 4 views
9

ほとんどすべてのC++プロジェクトにはコピーc-tor/copy operator/serializeメソッドなどのクラスがあります。c-tor/copy o-tor/serializationのリマインダーをコピーする新しいメンバーを追加する

しかし、開発者はこの機能に新しいメンバーを追加することを忘れてしまうことがあります。
開発者に何かをさせるか、この機能でnoop(memeber_name_)を書くように促す簡単な、ラップの全メンバーの方法をご存じですか?

私は何かを発明しようとしましたが、失敗しました。

PS:ユニットテストでこの問題を防ぐことができましたが、何かコンパイル時にしたいです。このように使用

答えて

1
template<class T> 
class SafeMember { 
public: 
    T _; /* short name for convenience */ 
    SafeMember(T const& obj) : _(obj) { } 
}; 

class Student { 
public: 
    Student(string surname, Color hairColor) 
     : surname(surname) 
     , hairColor(hairColor) { } 

    Student(Student const& other) 
     : surname(other.surname) 
     , hairColor(other.hairColor) { } 

    Student& operator=(Student const& other) { 
     surname = other.surname; 
     hairColor = other.hairColor; 
     return *this; 
    } 

    string getSurname() const { return surname._; } 

    // The foo._ syntax is better than implicit conversion because 
    // it lets us call member functions, like substr in this example: 
    bool isSlavic() const {return surname._.substr(surname._.size()-2)=="ev";} 

    void dyeHair(Color newColor) { hairColor = newColor; } 

private: 
    SafeMember<string> surname; 
    SafeMember<Color> hairColor; 
}; 

あなたが「SafeMember<int> age」メンバーを追加し、コピーコンストラクタを更新するのを忘れたときに今、コンパイルが親切に失敗します。

"ノーオペレーション"ヒントの場合、開発者は ":age(0)"のようなイニシャライザを追加します。

注:これは演算子=()またはserialize()関数をビットロートから保護するものではなく、コンストラクタのみを保護します。うまくいけば、これで十分であるはずです:コンストラクタからの抜けが見えたら、おそらく他の関数も覚えているでしょう。

+0

。 –

+0

さて、SafeMemberは、それらをラップするのに十分簡単です。私は、OPがそれらを包むのを避けたいと思う。 –

+0

申し訳ありませんが、新しいメンバ変数で動作します.. 私は既定のコンストラクタのリマインダを持っています。 – bayda

0

あなたの問題に満足できる解決策がないようです(イランビランジャの解決策はおそらく最良のアプローチの1つですが、それでも完全ではありません)。今後のC++ 0xにはこれを解決する機能があるのだろうか?

+0

している私は、受け入れ可能な解決策を発見しようとし続けています:) C++ 0xのが問題を解決するためのいくつかのツールを持っている場合それは許容されます。 C++ 0xドラフトをチェックします。 – bayda

+0

コンパイラがそれをチェックして、一部のメンバーがコピーされていないという警告を出すかもしれません...しかし、あなたはあなたがメンバーについて気にしないとどのように言いますか... –

1

この機能をユニットテストに追加します。単体テスト/デシリアライゼーション(例えば、deser(ser(x)) == xを確認している)を対象とする単体テストでは、単体テスト中に直列化関数にメンバを追加できないことがあります。同じことがコピーのctorsのために働くことができます。

コンパイル時のエラーと同じくらい理想的ではありませんが、単体テストフレームワークが適切で、適切なカバレッジがあることを確認した場合、これらの無視のエラーは難しくなります。

+1

応答に感謝します。一般的には、単体テスト - いいことですが、私は単体テストでの制御について考えました。しかし、メンバーをoperator ==に追加してassert(deserialize(serialize(x))== x)または 'y = x; assert(y == x);使用された関数の中にメンバーを追加することを忘れてしまっても問題ありません。 – bayda

0

私はこの問題を避ける最善の方法は、ルートでカットすることです:カスタムコピー演算子/コンストラクタを使用しないでください。

「すべてのメンバーの道をwrappない」これは常に可能ではないかもしれないが、ほとんどの場合、私は本当にそれだと思う...

関連する問題