假设我有一个主窗口。主窗口有一些子窗口,包括记录发生情况的日志窗口和操作用户数据的许多操作窗口。在操作窗口中的每个操作之后,我想在日志窗口中记录它。有几种方法可以实现它。
在操作窗口中放置指向日志窗口的指针。为此,我认为操作窗口不是那么可重用,因为它绑定到指针。总有一天,如果我不想记录,我需要删除它。而且,这种方式可能需要更多的记忆。另外,如果操作窗口是主窗口的孩子的孩子的孩子......,我需要逐个将指针传递到里面。
使主窗口成为单例并向其添加公共日志功能。当我需要记录时,我只需要调用MainWindow :: Inheritance() - > Log(theInformation)。但是,如果有一天我有2个主窗口会发生什么。
对此问题有任何好的建议。非常感谢!
答案 0 :(得分:1)
我认为正确的解决方案是将日志记录数据放入一个完全独立的类中,其目的是仅来存储和检索(以及截断,保存和...)日志信息。然后,需要记录数据的所有其他窗口,类等都需要访问单个日志类指针。
logSystem->log("my friend is blue");
现在,无论logSystem是全局还是在初始化期间传递给每个类的对象都取决于您。任何有许多“全球化都是邪恶的”阵营和“全球派都很有帮助”的人都会帮助你处理这个单独的问题。
然后,在您的日志记录窗口中,您只需要检索已记录的数据并显示它。
// Qt, C++-11 pseudo-api
foreach(String log, logMessages) {
myListBox->append(log);
}
这种方法的另一个优点是您可以打开和关闭(创建和销毁)日志窗口,但仍然不会丢失数据本身。是的,你也可以隐藏日志窗口或其他技巧,但能够完全销毁和重新创建它似乎更清洁。更不用说,通过从日志窗口中分离出日志数据,您可以稍后创建两个窗口,显示两组不同的日志记录数据。 [假设您没有使用全局记录数据,如上所述。]
答案 1 :(得分:1)
我通常会将记录器写成单身。
如果要删除日志记录功能,可以很容易地设置标志(用于运行时日志记录控制),或者用虚拟类替换它(用于编译时日志记录控制)。
所以从最基本的角度来看,你可能有:
Log::Get().Error("Name truncated by %u bytes", nBytes );
是的,我喜欢使用variadic printf样式的日志记录功能,但你可能更喜欢只有一个字符串或使用C ++流操作符。
如果我想要多个日志,我会把它变成一个可重用的类,并将它们的实例放到另一个单例中(例如一个'应用程序'类)。在那种情况下,我可能会:
Log::EventsLog().Info("Something exciting happened" );
Log::SystemLog().Info("Shutting down" );
当你的日志消息可以同时被调用时,你通常需要对你的日志消息进行某种形式的互斥控制。如果通过单线程队列将消息传递到日志窗口(如在Windows消息传递中),则可能不需要这样做。
答案 2 :(得分:0)
我原以为日志记录功能应该作为一个独立的“单例”类来实现......