I am trying to implement a logging factory and I have used an interface so that I can swap loggers whenever I like.
Here is the 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
};
And here is a derived class (header)
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
};
And 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);
}
Now here is the problem. See in the ILogger interface, I have commented out a private section of code? Well that is intended to stop anyone copying an ILogger derived class (like boost::noncopyable does). This makes sense (to me anyway) as it disallows separate instances of loggers from accessing the same file, and make the user go through my handy LoggerFactory.
When these lines are included then I get the following error:
genericloggerimpl.cpp(6) : error C2512: ‘ILogger’ : no appropriate default constructor available
What is that about? I do not want these objects to be copyable. How can I do that?
The existence of any user-defined constructor (which includes a copy-constructor) will prevent the compiler from generating a default-constructor. Your subclass
GenericLoggerrelies on the existence of a default-constructor forILogger(it is implicitly called, since it is not specified otherwise in the initialization-list of the constructor ofGenericLogger), hence the error.To fix the problem, simple declare a protected trivial default constructor for
ILogger: