我在 Linux 上有一个 C++ 类,它允许我根据应用程序的运行位置在控制台上显示消息。如果它在我的电脑上工作,消息将以控制台模式显示。否则,所有内容都记录在文本文件中供以后查看。我创建了一个外部对象来使用它。我想尝试让这个类(class)成为单例,但没有成功。我在编译我的程序时出现了这个错误:
error: invalid operands of types 'Log *' and 'const char [12]' to binary 'operator <<'
还有:
error: no match for 'operator <<' in 'logOutput' << Buffer_T ....
我想听听您的意见。预先感谢您的关注。
我目前的功能类
typedef std::vector<unsigned char> Buffer_T;
class Log
{
public:
Log();
virtual ~Log();
void init()
{
#indef FriendlyArm
output = new ofstream("/home/arm/Log.txt");
#else
output = &cout;
#endif
}
template<typename T>
Log operator<<( T const& value )
{
(*output) << value;
return *this;
}
Log& operator<<( std::ostream&(*f)(std::ostream&) )
{
(*output) << f;
return *this;
}
Log& operator<<(Buffer_T& Buf)
{
if( Buf.size() > 0 )
{
for( unsigned int i = 0; i < Buf.size(); i++ )
{
if( Buf[i] >= 32 && Buf[i] <= 127 )
{
(*output) << Buf[i];
}
else
{
(*output) << "0x" << std::setfill( '0' ) << std::hex << std::setw( 2 ) << unsigned( Buf[i] );
}
}
}
return *this;
}
private:
ostream *output;
};
#endif /* LOG_H_ */
这是我尝试的单例
typedef std::vector<unsigned char> Buffer_T;
class Log
{
public:
static Log *createOrGet()
{
if(_unique == NULL)
{
_unique = new Log();
}
return _unique;
}
static void kill()
{
if(_unique != NULL)
{
delete _unique;
_unique = NULL;
}
}
void init()
{
#indef FriendlyArm
output = new ofstream("/home/arm/Log.txt");
#else
output = &cout;
#endif
}
template<typename T>
Log operator<<( T const& value )
{
(*output) << value;
return *this;
}
Log& operator<<( std::ostream&(*f)(std::ostream&) )
{
(*output) << f;
return *this;
}
Log& operator<<(Buffer_T& Buf)
{
if( Buf.size() > 0 )
{
for( unsigned int i = 0; i < Buf.size(); i++ )
{
if( Buf[i] >= 32 && Buf[i] <= 127 )
{
(*output) << Buf[i];
}
else
{
(*output) << "0x" << std::setfill( '0' ) << std::hex << std::setw( 2 ) << unsigned( Buf[i] );
}
}
}
return *this;
}
private:
Log();
virtual ~Log();
static Log *_unique;
ostream *output;
};
Log *Log::_unique = NULL;
#endif
最佳答案
重要提示:不要以错误的方式理解它,但您犯了一些错误表明您不是很有经验并且单例很难正确使用。在记录器的情况下,它们没问题,只要确保始终将它们用作最后的手段。
我没有时间去解释为什么 operator<<
对你不起作用,但这里有一些关于如何改进你的单例的提示(你似乎也在寻求这方面的建议)。
实例函数
// The idiomatic way is to call this function 'Instance',
// but this doesn't really matter.
static Log& Instance() {
static Log obj;
return obj;
}
这就是所谓的迈耶单例。对于单线程应用程序,它很棒:实例在第一次调用函数时创建,自动在应用程序关闭时销毁(您不需要 kill
函数)。
您的私有(private)虚拟析构函数
我注意到你有一个私有(private)的虚拟析构函数。当类中至少有一个其他虚函数时,您只需要一个虚析构函数。不是这种情况;使析构函数成为非虚拟的。
强制执行单个实例
您将构造函数设为私有(private) — 这很好,您阻止我直接创建单例的多个实例。但是你并没有阻止我复制现有的单例。为了防止这种情况发生,您还需要将 CopyConstructor 和 AssignmentOperator 设为非公开:
protected:
Log();
Log(const Log&); // CopyConstructor
Log& operator=(const Log&); // AssignmentOperator
~Log();
(析构函数也应该是私有(private)的,以防止我删除该类的唯一实例。)
另请注意我制作了它们 protected
, 不是 public
.如果您不知道其中的区别,请查找(这里没有足够的空间来解释)。我做了它们protected
所以你可以继承自 Log
如果需要,请上课。
关于c++ - 运算符<<在单例中的重新定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8084812/