質問

関数インターフェイスがあります:

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

そして、アイデアはそれを取得することです:

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

しかし、私は時折、私は間違いをして書いています:

Type type = iface.getType();

これは価値ごとにコピーします。これは私が避けたいものです。ただし、そのような間違いを犯した場合、コンパイラは法的構文のために警告を発しません。このためにコンパイル時間エラーをトリガーしたいのですが、 質問 私の選択肢は何ですか?

私はコピーコンストラクターを宣言することを考えましたが、どこにも定義しないため、使用されている場合はリンク時間エラーが発生しますが、コピーコンストラクターを使用することはできません。 どれか 状況、それは必須ではありません

役に立ちましたか?

解決

コピーコンストラクターと割り当てオペレーターを「プライベート」に置くことにより、Ifaceを非コピーにします。次に、明示的なコピー方法を提供します。

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

使用することもできます コピーできないブースト 同じことをするために(上記のように実装)。

だからあなたのコードをコピーしたいなら、あなたはそうするでしょう

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

余談です - パフォーマンスの懸念のためにこれを行っている場合、オプティマイザーがあなたのための一時的なコピーを取り除いていないと確信していますか?

他のヒント

ここではポインターを返すと合理的に思えますが、所有権を混乱させると心配すると、参照の周りにラッパーを返すことができます。

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

元のクラスは通常どおりコピーできますが、参照は明示的に行う必要があります。私はこのアイデアに熱心ではありません(セマンティクスのコピーがどのように機能しているかを理解していないユーザーは、これらの1つが長すぎると誤って保持している人よりも少ないと思います)が、理論的には実行可能です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top