c++ - 运算符<<在单例中的重新定义

标签 c++ linux pointers singleton operator-overloading

我在 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/

相关文章:

c++ - 我的标准偏差程序的输出问题

python - Pascal 类型化二进制文件的 C++ 和 Python 类似物

java - 在 Windows、OSX 和 Linux 上获取进程的 PID

c++ - 字符、指针、强制转换和字符串问题

c++ - 互斥体更改是否会广播到多核系统上的其他内核?

django - 无法从同一台 AWS EC2 Linux 机器中调用 Django REST API

linux - 如何在 UNIX 中将 AWK 的多行输出插入到数组中

c++ - 解决 VS 2003 中的 C++ 指向成员的错误

c - C程序使用结构重新排列列表

c++ - OpenCV:带有 Alpha channel 的 PNG 图像