在我的项目中,一些类被多次实例化。每个类记录一些事件。日志记录方法是一个在项目周围使用的通用方法,它使用标准的 cout 。日志消息包含时间,类的名称,方法的名称,变量值和自定义消息。
缺点是日志不是特定于实例的。我不知道该类的哪个实例写了日志。
有没有一种很好的方法来解决这个问题,而无需在类中添加额外的静态成员作为实例计数器?我正在使用boost和C ++ 11。也许助推有可能有所帮助。
我能想到的唯一解决方案是将实例地址(this)包含在日志中。
答案 0 :(得分:1)
您需要区分不同的类某处,这些是一些选项(都依赖于某种ID):
this
:this
和哈希值:老实说,我认为2)并没有多大区别,但它可能引发一些进一步的想法。一些丑陋的黑客看起来像这样:
#include <iostream>
#include <functional>
#include <cstddef>
class Logger
{
public:
static void log(void* ptr)
{
using hash_type = std::uintptr_t;
std::cout << std::hash<hash_type>{}(reinterpret_cast<hash_type>(ptr))
<< " logged something..." << std::endl;
}
};
您还可以考虑为您的类specializing std::hash
并在日志记录输出中使用它。如果实施得当,这将消除在不同运行之间更改地址的问题。
结论: 我会选择1)如果人们的可读性受到关注,2)如果你只想要一些数字来区分日志信息(例如管道和过滤)。
答案 1 :(得分:1)
您可以通过CRTP适配器轻松生成ID(如果您可以稍微修改一下类)
template<typename T>
struct enable_id
{
int id = global_id++;
private:
static int global_id;
};
template<typename T>
int enable_id<T>::global_id = 0;
class foo : public enable_id<foo>
{
};
template<typename T>
void log(const T& t)
{
// if is_base_of
std::cout << t.id << std::endl;
}
答案 2 :(得分:0)
如果只有几个类实例,我建议您引入一个字符串成员,并在创建对象时使用唯一名称对其进行初始化。它将帮助您阅读日志。默认情况下,它可以使用对象的地址进行初始化。