Интерфейс с не копируемыми функциями - PullRequest
4 голосов
/ 12 августа 2011

Я пытаюсь реализовать фабрику журналирования, и я использовал интерфейс, чтобы я мог менять регистраторы в любое время.

Вот интерфейс

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.

Когда эти строки включены, я получаю следующую ошибку:1014 *

genericloggerimpl.cpp (6): ошибка C2512: 'ILogger': не доступен соответствующий конструктор по умолчанию

О чем это?Я не хочу, чтобы эти объекты были копируемыми.Как я могу это сделать?

Ответы [ 2 ]

2 голосов
/ 12 августа 2011

Наличие любого определяемого пользователем конструктора (который включает конструктор копирования) не позволит компилятору генерировать конструктор по умолчанию.Ваш подкласс GenericLogger полагается на существование конструктора по умолчанию для ILogger (он вызывается неявно, поскольку он не указан иначе в списке инициализации конструктора GenericLogger), следовательно, ошибка.*

Чтобы устранить проблему, просто объявите защищенный простой конструктор по умолчанию для ILogger:

ILogger() {}
1 голос
/ 13 августа 2011

Вы можете наследовать от следующего класса, чтобы отключить копирование для любого класса, который хотите защитить:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...