一般问题是我喜欢构建写入单个日志文件的logger类 从我的应用程序中的不同类,记录器类应该是什么 单音或静态类
答案 0 :(得分:8)
是什么让你觉得它应该是?那些可以根据需要实例化的常规非静态类呢?然后将其中一个静态实例作为默认记录器。通过这种方式,您可以获得两全其美:方便的全局访问记录器和测试它或临时使用其他记录器的能力。
另一个建议是简单地创建一个实例并将其作为参数传递给类的每个组件,如@disown所示。
但是,如果你让这个课程本身是静态的或是一个单身人士,你只是在自己的脚下拍摄。
修改强>
例如,回应@ Stephen的评论:
// define a logger class, a perfectly ordinary class, not a singleton, and without all static members
class Logger {
// ....
};
// create a single global *instance* of this class
Logger defaultLog;
void foo() {
// and now use the globally visible instance
defaultLog.Log("hello");
// or create a new one if that's what we need:
Logger newlog;
newlog.Log("hello");
}
没有魔力。这正是标准库的功能。 std::cout
不是单身人士。它只是类std::ostream
的全局实例,这个类也可以在需要时正常实例化。
答案 1 :(得分:3)
在C ++中,你需要一个单例而不是静态。 C ++不允许您控制构造和销毁静态对象的顺序,如果您在构造静态之前尝试记录,则行为可能是未定义的。
我不确定Java。
答案 2 :(得分:0)
答案当然是“这取决于。”
首先,如果我是你,我不会重新发明轮子而只使用Log4j。如果它不能满足您的确切要求,那么最好不要从头开始扩展不满足您需求的log4net的一个组件(例如自定义日志源)。其次,静态类可能足以用于简单的日志记录类。对于更复杂的事情,单身类可能是最佳选择。
答案 3 :(得分:0)
在C ++中,您可以使用此习惯用于延迟初始化:
Foo& getInstance()
{
static Foo instance;
return instance;
}
答案 4 :(得分:-1)
不要使用单例或静态,使用依赖注入,即在main()中实例化一个实例,并将对该实例的引用传递给所有依赖类。静态和/或单例几乎不是必需的,并且通常会导致代码不太优雅。
答案 5 :(得分:-1)
我可能会使用单例,但不管怎样,将其隐藏在函数或宏后面。不要让人打字
MySuperSpectacularLogger::GetInstance()->Log("adssdf");
改为使用:
void Log(cpnst string& msg) {
MySuperSpectacularLogger::GetInstance()->Log(msg);
}
甚至更好:
// Logs 'msg' with the filename and line number that generates it.
#define LOG(msg) \
MySuperSpectacularLogger::GetInstance()->Log(__FILE__, __LINE__, msg);