【问题标题】:Problems with operator << in a Singleton Log class单例日志类中运算符 << 的问题
【发布时间】:2015-10-23 12:34:21
【问题描述】:

我正在尝试实现一个使用“

int _tmain(int argc, TCHAR* argv[])
{
    SLog& log = SLog::getLogInstance();
    log << output::screen << "Test" << endl;
}

[是的,我知道_tmain() 是一个可怕的 Windows hack - 我只是想学习这些东西,这是我目前推送 unicode 的最简单方法;以后会担心跨平台的]

我的问题是我的模板函数永远不会被调用;它似乎总是调用基础wostream。以下是有关实施的更多信息: --SLog.h--

enum class output : int
{
    screen = 0,
    file,
    both
};

class SLog
{
private:
    TOSTREAM* m_pO;
    output m_Output;

    SLog();         // Private ctor; no instantiation allowed
    ~SLog();        // Private dtor; no way to kill it
    SLog(SLog const&) {};   // Private copy ctor; copying is a no-no
    SLog& operator = (SLog const&) {};  // Private - no assignations
public:
    template<typename T>
    TOSTREAM& operator<<(const T& statement)
    {
        switch (m_Output)
        {
        case output::file:
            if( NULL != m_pO )
                *m_pO << statement;
            break;
        case output::both:
            TOUT << statement;
            if( NULL != m_pO )
                *m_pO << statement;
            break;
        default:            // default to screen
            TOUT << statement << " like a boss...";
            break;
        }

        if (NULL != m_pO)
            return *m_pO;
        else
            return TOUT;
    };

    TOSTREAM& operator<<(const output& statement);
    static SLog& getLogInstance();
};

这是 SLog.cpp:

SLog & SLog::getLogInstance()
{
    static SLog log;
    return log;
}

SLog::SLog()
{
    m_pO = new TOSTREAM(TOUT.rdbuf());

    // Initially set the output to go to the screen
    m_Output = output::screen;  
}

SLog::~SLog()
{
    // Is our logging output stream still good?
    if (NULL != m_pO)
    {
        m_pO->flush();  // flush it, in case there's still output
        delete m_pO;    // free the memory I allocated in the ctor
    m_pO = NULL;    // Set it to null to be sure we can't use it
    }
}

TOSTREAM & SLog::operator<<(const output & statement)
{
    m_Output = statement;
    if (NULL != m_pO)
        return *m_pO;
    else
        return TOUT;
}

我在这里定义了 TOUT、TOSTREAM 等:

#if defined(UNICODE) || defined(_UNICODE)
#define TERR        std::wcerr
#define TOUT        std::wcout
#define TSTRING     std::wstring
#define TSSTREAM    std::wstringstream
#define TOSTREAM    std::wostream
#define TOFSTREAM   std::wofstream
#define TNPOS       std::wstring::npos
#define SPRINTF     swprintf_s
#else
#define TERR        std::cerr
#define TOUT        std::cout
#define TSTRING     std::string
#define TSSTREAM    std::stringstream
#define TOSTREAM    std::ostream
#define TOFSTREAM   std::ofstream
#define TNPOS       std::string::npos
#define SPRINTF     sprintf_s
#endif

[添加&lt;&lt; " like a boss..." &lt;&lt; 只是为了查看我是否正在调用我的函数,因为我尝试了各种方法来打印它;它从来没有,当我设置断点并通过时,我只是通过基础wostream 实现...]

所以,我显然不是我认为的 C++ 程序员;我在这里做错了什么??

【问题讨论】:

    标签: c++ unicode singleton operator-keyword ostream


    【解决方案1】:

    看来你忘了测试小例了。

    log << "Test" << endl;
    

    输出

    Test like a boss...
    

    如您所愿。
    但是

    log << "Test" << " more test" << endl;
    

    输出

    Test like a boss... more test
    

    您的流插入操作符返回TOSTREAM &amp;,因此只有第一项进入SLog

    他们应该返回一个SLog&amp;,即*this

    SLog & SLog::operator<<(const output & statement)
    {
        m_Output = statement;
        return *this;
    }
    

    另一个运算符留作练习。

    【讨论】:

    • 当我试图弄清楚发生了什么时,我实际上尝试过。问题是返回 SLog&amp; 不允许像 log &lt;&lt; "TEST01" &lt;&lt; endl; 这样的复合语句; &lt;&lt; endl; 给出no operator "&lt;&lt;" matches these operands. operand types are: SLog &lt;&lt; &lt;unknown-type&gt;&lt;iostream&gt;&lt;iomanip&gt; 都是 #included。当我尝试编译时,我得到一个类似的C2679: binary '&lt;&lt;': no operator found which takes a right-hand operand of type 'overloaded-function' (or there is no acceptable conversion)
    • @KennG std::endl 是一个函数模板。您可以为其添加重载。 (如果你想让std::basic_ostream 完全像一个一样使用,你将需要它所具有的所有重载。)
    • 为了结束,我使用了您的建议(谢谢)并进行了更多挖掘并最终得到以下结果(有效,以防万一其他人尝试这样做):@987654340 @
    猜你喜欢
    • 1970-01-01
    • 2013-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多