在函数入口处将字符串预先添加到记录器

时间:2010-10-28 04:52:27

标签: c++

我有一个记录器类。称之为MyLogger。我可以在这样的函数中使用它:

void MyFunc(MyLogger& oLogger)
{
   //Do stuff
   oLogger.Log("In MyFunc : Some Error");
   //Do something else
   oLogger.Log("In MyFunc : Some other error");
}

现在,如果日志来自"In MyFunc",我想在日志前加MyFunc。与其他功能类似......

因为这很无聊,我尝试过这样的事情:

void MyLogger::PushPrependString(const char*)
{
   //Store prepend string in stack and set it as current prepend string.
}

void MyLogger::PopPrependString()
{
   //Pop the most recent prepend string.
}

现在,我可以使用这两个函数:

void MyFunc(MyLogger& oLogger)
{
   oLogger.PushPrependString("In MyFunc : ");
   //Do stuff
   oLogger.Log("Some Error");
   //Do something else
   oLogger.Log("Some other error");
   oLogger.PopPrependString();
}

问题是,如果函数中有多个return,这就变得很难看。有没有办法解决?这是个常见的问题吗?是否有任何预处理器宏,如__FILE____LINE__,用于获取一行显示的函数名称?任何意见将不胜感激。感谢。

2 个答案:

答案 0 :(得分:3)

“麻烦的是,如果一个函数中有多个返回,这会变得很难看。有什么方法可以解决这个问题吗?”

是的,只需使用带构造函数的对象(调用PushPrependString)和析构函数(调用PopPrependString)。

class LogPrefix
{
private:
    MyLogger* logger_;

    LogPrefix( LogPrefix const& );              // No such.
    LogPrefix& operator=( LogPrefix const& );   // No such.
public:
    LogPrefix( MyLogger& logger, char const s[] )
        : logger_( &logger )
    {
        logger_->PushPrependString( s );
    }
    ~LogPrefix()
    {
        logger_->PopPrependString();
    }
};

免责声明:关闭袖口代码,不要被编制者的手接触......

“这是一个常见的问题吗?”

“有没有像 FILE LINE 这样的预处理器宏来获取一行出现的函数名称?”

不在C ++ 98中。各种编译器提供了各种扩展功能。 IIRC C ++ 0x采用C99方案,遗憾的是它只提供静态字符串。

干杯&第h

答案 1 :(得分:2)

RAII - 资源获取正在初始化。

在这种情况下,您在函数入口处创建一个对象,该对象标识日志系统的当前函数;当函数退出时(通过任何返回或异常抛出或异常未捕获),对象将被销毁,析构函数将更改日志记录系统将来打印的内容。

在C99中,也许在某些C ++编译器(如G ++)中,有一个包含函数名的预定义变量__func__。我相信,C ++等价物更复杂。