2011-08-12 4 views
4

私はロギングファクトリを実装しようとしています。私は好きなときにいつでもロガーをスワップできます。ここコピー不可能な機能を持つインターフェイス

インターフェイス

class ILogger 
{ 
public: 

    //Only allow string input. The entire ARC is going to be non-unicode. 
    virtual void log(std::string message, eLogLevel level=DEBUG) = 0; 

protected: 
    virtual ~ILogger(void){}; 


private: 
    // No one can create an ILogger as it is abstract but should also 
    // disallow copying... why copy a logger? Only one per file. Besides want to 
    // force people to use the factory. 
    /*ILogger(const ILogger&); 
    ILogger& operator=(const ILogger&);*/ // REMOVED THIS BECAUSE OF ERROR 

}; 

そして、ここでは、派生クラス(ヘッダ)

class GenericLoggerImpl : 
    public ILogger 
{ 
public: 
    virtual ~GenericLoggerImpl(void); 
    virtual void log(std::string message, eLogLevel level=DEBUG); 

private: 
    GenericLoggerImpl(void); //USE THE FACTORY 
    std::tr1::shared_ptr<GenericLogger> pImpl; //This is the implementation 
    friend class LoggerFactory; // class LoggerFactory can now build these 
}; 

れ、CPP

GenericLoggerImpl::GenericLoggerImpl(void):pImpl() 
{ 
    pImpl = std::tr1::shared_ptr<GenericLogger> (new GenericLogger()); //This is the implementation 
} 

GenericLoggerImpl::~GenericLoggerImpl(void) 
{ 
} 

void GenericLoggerImpl::log(std::string message, eLogLevel level) 
{ 
    pImpl->logMsg(message.c_str(),level); 
} 

が今ここに問題があります。 ILoggerインターフェースを参照して、コードのプライベートセクションをコメントアウトしましたか?それは、ILogger派生クラスをコピーする人(boost :: noncopyableのように)を止めることを意図しています。これは、別のインスタンスのロガーが同じファイルにアクセスできないようにして、ユーザーが自分の便利なLoggerFactoryを通過できるようにする(私にとってはとにかく)意味があります。

これらの行が含まれている場合、私は次のエラーを取得する:

genericloggerimpl.cpp(6) : error C2512: 'ILogger' : no appropriate default constructor available

に関することは何ですか?私はこれらのオブジェクトをコピー可能にしたくありません。どうやってやるの?

+0

もう一度コンパイルする前に保存しましたか?そして私はあなたのコードで実際にILogger(サブ)オブジェクトを構築する呼び出しをどの部分が理解しているのか分かりません。 'GenericLogger'クラスはどのようなものですか? – Mahesh

+0

@Mahesh - 私は、いくつかの作成機能を提供する別々のLoggerFactoryオブジェクトを持っています。これは、実装クラスGenericLoggerImplの友人であることがわかります。 GenericLoggerはロギングクラスですが、かなり複雑です。 GenericLoggerImplはそのクラスのアダプターのように動作すると考えることができます。あるいは、GenericLoggerImplはILoggerであり、GenericLoggerの観点から実装されています。 – Dennis

答えて

2

任意のユーザ定義コンストラクタ(コピーコンストラクタを含む)が存在すると、コンパイラがデフォルトコンストラクタを生成できなくなります。サブクラスGenericLoggerは、​​のデフォルトコンストラクタの存在に依存します(コンストラクタの初期化リストに特に指定されていないので暗黙に呼び出されます)。したがって、エラーです。あなたが保護したい任意のクラスのためのコピーを無効にするには、以下のクラスから継承することができる

ILogger() {} 
+0

ありがとう、これは正常に動作します。 – Dennis

+0

@Dennis:別のヒント:Boostにアクセスできない場合は、['boost :: noncopyable'](http://www.boost.org/doc/libs/)を使うことができます。 release/libs/utility/utility.htm#Class_noncopyable)を使用して、オブジェクトがコピー不可能であることを表します。これはもう少し明示的でクリーナーです。 –

+0

良い点。私はコピー不可能なコピーが既にそこにあるかどうかを確認するためにプロジェクトリポジトリをチェックする必要があります。 – Dennis

1

:問題、シンプルな宣言​​のための保護された些細なデフォルトコンストラクタを修正するには

class no_copy 
{ 
protected: 
    // For derived class. Protected just to avoid direct instantiation of this class 
    no_copy(){} 

private:  
    no_copy(const no_copy&); 
    void operator =(const no_copy&); 
}; 

例:

class MyClass:public no_copy 
{ 
}; 

エラー:

MyClass cls1; 
MyClass cls2(cls1); // Error 
cls2 = cls1; // Error 
関連する問題