2011-04-27 7 views
1

を初期化するとき、私は関数インタフェースがあります。避けコピー参照

struct iFace { 
    virtual Type& getType() = 0; 
} 

をし、アイデアは次のようにそれを取得することです:

iFace& iface = getIface(); 
Type& type = iface.getType(); 

しかし、私は時折、私はミスを行うと書き込み:

Type type = iface.getType(); 

私は避けたい値でコピーします。しかし、私はそのような間違いを犯すと、コンパイラはその法的な構文のために警告を出しません。私はこのためにコンパイル時のエラーを引き起こしたいと思います質問私の選択肢は何ですか?

私はコピーコンストラクタを宣言することを考えましたが、それを使用するとリンク時エラーが発生しましたが、コピーコンストラクタを使用することができません。ANY状況は、

+0

あなたは本当にそれを両方の方法で持つことはできません。 –

+0

それは私が恐れているものなので、私は確認するためにここでそれを求めると思った。それを確認していただきありがとうございます – lurscher

+0

それはタイプによって異なります。タイプ抽象化を行うことができれば、インスタンスを作成することはできません。 –

答えて

8

iFaceをコピーできないようにするには、コピーコンストラクタと代入演算子を「private」にします。次に、明示的なCopyメソッドを提供します。

class Type { 
public: 
    virtual Copy(Type& dest) = 0; 
private: 
    Type (const Type &) {assert(false)} 
    Type & operator=(const Type &) {assert(false)} 
} 

boost noncopyableを使用して、上記と同じことを行うこともできます。

コピーするようにコードを望んでいたのであれば、あなたはさておきとして

Type& type = iface.getType(); 
Type typeCpy; 
type.Copy(typeCpy); 

を行うだろう - 私はあなたがあるため、パフォーマンス上の問題のこれをやっている場合は、あなたが特定されているオプティマイザがdoesnのことを追加したいですあなたのために一時的なコピーを取り除くことはありませんか?

+0

これは、コピーコンストラクターが使いにくくなった場合に該当します。 "これ以外のすべてが失敗した場合"の計画にしておきます。 – lurscher

+0

@lurscher、明示的なコピーを提供することもできます。私の編集を参照してください。 –

+0

明示的なキーワードを使用してコピーコンストラクタを制限できますか? – lurscher

-1

ここではポインタを返すのは妥当だと思われますが、混乱している所有者の心配があれば、参照の周りにラッパーを返すことができます。

struct Class { 
    struct Ref { 
     Ref(Class& c_) : c(c_) { } 
     Class Clone() { return c; } 
     // overload -> to provide access to c 
     private: 
     Class& c; 
    }; 
}; 

元のクラスは通常どおりコピーできますが、参照は明示的に行う必要があります。私はそのアイデアに熱心ではない(私は、コピーセマンティクスが、あまりにも長くかかることに偶然対処したものよりも、理解していないユーザーは少なく思うだろうが)、理論的には実行可能である。

関連する問題