C++ 在C+中调用静态成员的方法进行初始化+;

C++ 在C+中调用静态成员的方法进行初始化+;,c++,boost,C++,Boost,我有一个类,它有一个静态成员对象。初始化静态对象意味着将其某些参数设置为特定值;但这是由该对象的函数完成的。如果是静态的,我不知道怎么做。有什么帮助吗 更具体地说,每个类都有一个静态boost记录器对象。它有一个ClasName属性,通过add\u属性(“ClassName”,boost::log::attributes::constant(“MyClass”)函数将其设置为类的name\u。初始化静态记录器的最佳方法是什么?我已经做了: typedef boost::log::sources

我有一个类,它有一个静态成员对象。初始化静态对象意味着将其某些参数设置为特定值;但这是由该对象的函数完成的。如果是静态的,我不知道怎么做。有什么帮助吗


更具体地说,每个类都有一个静态boost记录器对象。它有一个
ClasName
属性,通过
add\u属性(“ClassName”,boost::log::attributes::constant(“MyClass”)
函数将其设置为类的
name\u。初始化静态记录器的最佳方法是什么?我已经做了:

typedef boost::log::sources::severity_logger< severity_levels > BoostLogger;

class MyClass
{
private:
  static BoostLogger m_logger;

public:
  MyClass()
  {
    MyClass::m_logger.add_attribute("ClassName", boost::log::attributes::constant<std::string>("MyClass"));
  }
}

BoostLogger MyClass::m_logger; // And here I cannot call the add_attribute() function
typedef boost::log::sources::severity\u loggerBoostLogger;
类MyClass
{
私人:
静态BoostLogger mu记录器;
公众:
MyClass()
{
MyClass::m_logger.add_属性(“ClassName”,boost::log::attributes::constant(“MyClass”);
}
}
BoostLogger MyClass::m_logger;//这里我不能调用add_attribute()函数

我知道每次实例化类时都会这样做,因此:最好的方法是什么?

您可以初始化记录器一次,例如,在构造函数中使用静态变量:

MyClass()
{
  static bool logger_initialised = false;
  if (!logger_initialised)
  {
    MyClass::m_logger.add_attribute("ClassName", boost::log::attributes::constant<std::string>("MyClass"));
    logger_initialised = true;
  }
}
MyClass()
{
静态布尔记录器_初始化=假;
如果(!logger_已初始化)
{
MyClass::m_logger.add_属性(“ClassName”,boost::log::attributes::constant(“MyClass”);
记录器_初始化=真;
}
}

请注意,这不是线程安全的。但是如果您不使用线程,它将工作,并且记录器将被初始化一次,但只有当您实例化
MyClass

而不是
add\u属性调用时,才可以使用它的构造函数完全初始化
BoostLogger
。然后在定义时只需提供必要的参数。

首先查看

这是您的代码的更正版本

MyClass.h:

class MyClass
{
private:
  static BoostLogger m_logger;  /*  This is declaration, not definition.
                                    You need also define the member somewhere */

public:
  MyClass() /*  So far as this is constructor, it may be called more than once,
                I think adding new static function will be better */
  {
    // MyClass::m_logger.add_attribute("ClassName", boost::log::attributes::constant<std::string>("MyClass"));
    // AddAttribute("ClassName"); Uncomment this line if you're really need to add attribute in constructor
  }

  static void AddAttribute(std::string name) /* this function has been added as advice,
                                                if you're going add attributes as you
                                                did in question,
                                                remove function, and uncomment first              line in the constructor */
  {
    MyClass::m_logger.add_attribute(name, boost::log::attributes::constant<std::string>("MyClass"));
  }
}
BoostLogger MyClass::m_logger = BoostLogger(); // This is definition of static member item

如果
BoostLogger
没有为
add\u属性提供构造函数,您可以为此创建自己的函数,例如:

class MyClass
{
private:
    static BoostLogger m_logger;
};

BoostLogger CreateBoostLoggerWithClassName(const std::string& className)
{
    BoostLogger logger;
    logger.add_attribute(
        "ClassName",
        boost::log::attributes::constant<std::string>(className));
    return logger;
}

BoostLogger MyClass::m_logger = CreateBoostLoggerWithClassName("MyClass");
class-MyClass
{
私人:
静态BoostLogger mu记录器;
};
BoostLogger CreateBoostLoggerWithClassName(const std::string&className)
{
BoostLogger记录器;
logger.add_属性(
“类名”,
boost::log::attributes::constant(className));
返回记录器;
}
BoostLogger MyClass::m_logger=CreateBoostLogger WithClassName(“MyClass”);

我想每个类只初始化静态记录器一次,而不是每个安装一次将行添加到任何初始化函数中。因此,我将创建一个静态
init
函数?是否需要至少有一个MyClass实例才能初始化
m_logger
?以任何方式或形式都不是线程安全的。也不是很优雅。@LightnessRacesinOrbit那么什么是最好的方式呢?没有最好的方式。这取决于初始化的成本。对于该类,它只需要一次或两次,但我还希望有其他类使用这种日志。我的意思是,如果您希望等待初始化,直到创建类的第一个实例,并且您不关心线程安全,请使用我的答案。好的,这是一个错误,它是一个
BoostLogger
,即
typedef boost::log::sources::severity\u loggerBoostLogger但我无法访问它。。。我要做一个非静态BoostLogger吗?哦,现在你告诉我们BoostLogger是什么。是什么阻止您在一开始就提供此信息?是的,我必须编辑这个问题。。。现在你可以看到定义在哪里了。如果你愿意,你不需要。请参见答案中我最后的更改。:)好的,你说我需要一个静态函数。但是这是最好的方法吗?没有区别,就是说没有区别。因此,从性能的角度来看,这两种版本的初始化都是正确和相同的。您可以同时使用这两个版本,并且不关心性能问题。顺便说一句,重载赋值运算符,您仍然会看到相同的输出。实际上,不能保证删除临时和副本。把它放在那里太傻了;毫无用处。