具有不可复制功能的界面

时间:2011-08-12 18:40:39

标签: c++ visual-c++ interface

我正在尝试实现一个日志工厂,并且我使用了一个接口,这样我就可以随时交换记录器。

这是界面

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):错误C2512:'ILogger':没有合适的默认构造函数

那是什么意思?我不希望这些对象是可复制的。我怎么能这样做?

2 个答案:

答案 0 :(得分:2)

任何用户定义的构造函数(包括复制构造函数)的存在将阻止编译器生成默认构造函数。您的子类GenericLogger依赖于ILogger的默认构造函数的存在(它被隐式调用,因为在GenericLogger的构造函数的初始化列表中没有另外指定),因此错误。

要解决此问题,请简单声明ILogger的受保护的普通默认构造函数:

ILogger() {}

答案 1 :(得分: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