0

从 C++ 开始,我编写了一段简单的代码,旨在用作(非常基本的)记录器。这主要是为了尝试重载运算符。

class Logger {

  public:
    Logger() : _has_logged_something(false) { };

    template <typename T>
    friend Logger& operator <<(Logger& logger, T const & value) {
      logger._has_logged_something = true;
      std::cerr << value;
      return logger;
    };

  private:
    bool _has_logged_something;

};

_has_logged_something我需要记住实例变量中何时已经加载了某些内容。但是这条线在运行时非常有帮助Segmentation fault (core dumped)。一定是一个明显的错误,但我无法理解。

--

编辑

因为这似乎不是这段代码的问题,所以这里是如何使用它来避免使用单例(可能不是最好的代码,但无论如何)。

#ifndef _BORDERS_COMMON_LOGGER_LOGGER_HH_INCLUDED
#define _BORDERS_COMMON_LOGGER_LOGGER_HH_INCLUDED

#include "common/log/logger.hh"
#include "common/log/event.hh"

namespace {
  static borders::common::log::Logger* _global_logger = NULL;
}

namespace borders {

  namespace common {

    namespace log {

      inline bool is_global_instance_initialized() {
        return _global_logger != NULL;
      };

      inline Logger& get_global_instance() {
        if (_global_logger == NULL) _global_logger = new Logger;
        return *_global_logger;
      };

    } // namespace log

  } // namespace common

} // namespace borders

#define LOG_INFO() (borders::common::log::get_global_instance())

#define LOG_START()
#define LOG_STOP() \
  if (borders::common::log::is_global_instance_initialized()) \
    delete &borders::common::log::get_global_instance(); \
  else \
    (void) 0;

#endif // _BORDERS_COMMON_LOGGER_LOGGER_HH_INCLUDED

鉴于我尝试使用以下方法运行它:

LOG_INFO() << "Foo" << "Bar"

再一次,当我注释掉我之前指出的行时,文本会写在控制台上。

4

1 回答 1

0

好,我知道了!

我认为。至少我有一个猜测

看,那行logger._has_logged_something = true是唯一使用类数据的行logger。所以我的猜测是这个类是无效的

我的意思是你并没有真正创建那个类。由于某种原因,它并没有真正分配。

例如,如果您这样做:

Logger *log; // see - I didn't put any value to it!

(*log)<<value; // this will do a segmentation fault or something 
               // ONLY if you have the line logger._has_logged_something = true

这只是一个例子。还有其他选项,例如:

struct blah{
  blah(Logger &log):logger(log);
  Logger &logger;
};
blah func(){
  Logger log;
  return blah(log);
}
...
blah b=func(); // b has an invalid logger in it, because it was destroyed after func
blah.logger << value ; // will do a segmentation fault too

编辑

刚看到你的编辑。所以这似乎是我的第一个例子。具体来说,我相信您LOG_STOP()在登录之前就这样做了。

编辑 2

您的代码中有一个内在问题。LOG_STOP删除记录器,但不会将其重置为NULL. 因此,如果您想在那之后重新开始记录,则不会重新创建记录器(在决定创建get_global_instance记录器之前检查记录器是否存在)。NULL

尝试更改LOG_STOP设置_global_logger为 NULL 并查看是否可以修复它。

于 2013-09-26T16:50:41.577 回答