2011-01-23 6 views
3

iはFoo、 とそのコンストラクタの1だけでFooへの参照を受け取るために起こるコピー不能クラスがあるとします。それはコピーとは全く関係のない何かをしながらは、コンストラクタはFoo :: Fooのはfooへの参照を受け取るが、コピーコンストラクタではない

class Foo 
{ 
public: 
    Foo(Foo& parent) {...} 

private: 
    void operator=(Foo); // disabled 
    ... 
}; 

コンパイラが(そう代入演算子が無効になっている)、これはコピーコンストラクタ、 だと思います。

このようにコンストラクタを定義する際には、 の危険性がありますか、その署名を人為的に変更する必要がありますか?参照の代わりにポインタ、 を使用するか、または必須のダミーパラメータを追加しますか?

ここにいくつかの文脈があります(私の質問を理解する/答えなくてもいいかもしれません)。

自分で書いたクラスライブラリ は、ユーザーコードと別のライブラリの間の接続として機能します。 他のライブラリは簡潔にするためと書かれたサービスを提供しています。 ユーザーコードは次のようになります。

class UsefulObject: public mylib::Frobnicator 
{ 
    ... 
    void DoStuff() 
    { 
     int x = ... 
     ... 
     frobnicate(x); // it's important to allow simple syntax here 
     frobnicate(x + 1); 
     ... 
    } 
    ... 
}; 

私はユーザーオブジェクトの階層をサポートする:各オブジェクトは、別の(親)に含まれ、 数(私の場合は、5)のトップがありますがすべての他のオブジェクトを含むレベルのオブジェクト。

各オブジェクトにはログファイルがあります。私は各呼び出しが複数のログファイルに記録されるようにしたい、 トップレベルオブジェクトまで包含階層を上にしてください。

私はそれがこの方法を実装している:

namespace mylib 
{ 
    class Frobnicator // provides the frobnication service 
    { 
    public: 
     Frobnicator(Frobnicator& parent): parent(parent) {} 
    protected: 
     virtual void frobnicate(int x) { 
      ... // some logging code 
      parent->frobnicate(x); 
     } 
    private: 
     Frobnicator& parent; 
    }; 

    namespace internal // users of mylib, please don't use this! 
    { 
     class TheUltimateFrobnicator: public Frobnicator 
     { 
     protected: 
      virtual void frobnicate(int x) { 
       the_other_library::frobnicate(x); 
      } 
     private: 
      TheUltimateFrobnicator(int id); // called by a factory or some such 
     }; 
    } 
} 
+0

"コンパイラはこれがコピーコンストラクタであると考えています"。あなたがコピーをしたくない場合でも、定義上、コピーコンストラクタです。 –

答えて

7

これには、コンストラクタの意味で不幸な曖昧であるように思われます。私は、パラメータはとにかくポインタであることを期待する多くの人々を知って、これを明確にする最も簡単な方法は、

class Frobnicator // provides the frobnication service 
{ 
public: 
    explicit Frobnicator(Frobnicator *parent): parent(parent) {} 
protected: 
    virtual void frobnicate(int x) { 
     ... // some logging code 
     parent->frobnicate(x); 
    } 
private: 
    void operator=(Foo); // disabled 
    Frobnicator(Frobnicator const&); // disabled 

    Frobnicator *parent; 
}; 

ポインタを使用することだと思います。ちなみに、parent.frobnicateparent->frobnicateと間違えて入力しました。

+1

コンストラクタを明示的に宣言していないのですか? –

+0

@Peterああ、私は今参照してください。あなたが正しいです。私はそれを修正します。 –

+0

素晴らしい:-)元のケースはいかがですか? '明示的なFrobnicator(Frobnicator&parent)'は、コンパイラがそれを悪用するのを防ぐのではないでしょうか? –

関連する問題