在公司的代码里面看到了一个C++的wrapper class,以前没有见过这样的封装,贴出来备忘。
class LoggerPtr
{
private:
// Pointer to a logger object owned by client
Logger *m_logger;
// Instance of a Null Logger, to be used when we don't
// have a pointer to an actual logger.
NullLogger m_nullLogger;
public:
// Default constructor. This constructor is marked as explicit
// since we don't want IQscLoggerPtr objects being created
// 'on the fly' (i.e. implicitly).
explicit LoggerPtr(Logger *logger = 0) : m_logger(logger)
{
}
// Destructor. We don't delete the logger pointer, since it is owned by
// our client.
virtual ~ILoggerPtr()
{
}
// Overload for -> operator that returns a pointer to a logger interface
// if it exists, or a pointer to a Null Logger otherwise.
inline Logger * operator->() const
{
if (m_logger)
{
return m_logger;
}
else
{
// We don't have a logger, so return a pointer to the Null
// logger.
return const_cast<Logger *>((const Logger *)&m_nullLogger);
}
}
// User Defined Conversion operator to return a pointer to encapsulated
// logger object, or a pointer to a Null logger if one doesn't exist.
inline operator Logger *() const
{
if (m_logger)
{
return m_logger;
}
else
{
// We don't have a logger, so return a pointer to the Null
// logger.
return const_cast<Logger *>((const Logger *)&m_nullLogger);
}
}
LoggerPtr & operator = (Logger *logger)
{
m_logger = logger;
return *this;
}
// Sets internal logger pointer
void Logger(Logger *logger)
{
m_logger = logger;
}
}
它封装了IQscLogger。这样的好处是如果使用者用到了一个空的logger,那么也不会引起什么问题。当然这样做似乎也有个问题,如果确实是使用者的疏忽造成的,这样处理是不是还不如产生一个严重错误呢?从这个意义上来讲,null logger更像是一个default logger。