C++ 调用构造函数初始值设定项列表中的函数可以吗?

C++ 调用构造函数初始值设定项列表中的函数可以吗?,c++,constructor,variable-initialization,C++,Constructor,Variable Initialization,我的直觉是它不是。我的情况如下: class PluginLoader { public: Builder* const p_Builder; Logger* const p_Logger; //Others }; PluginLoader::PluginLoader(Builder* const pBuilder) :p_Builder(pBuilder), p_Logger(pBuilder->GetLogger()) { //

我的直觉是它不是。我的情况如下:

class PluginLoader
{
   public:
      Builder* const p_Builder;
      Logger* const p_Logger;

      //Others
};

PluginLoader::PluginLoader(Builder* const pBuilder)
   :p_Builder(pBuilder), p_Logger(pBuilder->GetLogger())
{
   //Stuff
}

或者我应该更改构造函数并传递一个
Logger*const
从哪里构造
PluginLoader

这很正常
p_Builder
是在它之前初始化的。

非常好的实践

我建议这样做(但这纯粹是个人层面的):


不要在构造函数中调用函数,而是在init函数中对它们进行分组,这只是出于灵活性的目的:如果以后必须创建其他构造函数的话。

您所拥有的一切都很好。然而,我只是想提醒你小心不要这样做(GMan提到了这一点,我只是想说清楚)

请注意,我对您的代码做了2处更改。首先,在类定义中,我在p_Builder之前声明了p_Logger。其次,我使用成员p_生成器来初始化p_记录器,而不是参数

这些更改中的任何一个都可以,但是它们一起引入了一个bug,因为p_记录器首先被初始化,而您使用未初始化的p_构建器来初始化它


只要记住,成员是按照它们在类定义中出现的顺序初始化的。而您将它们放入初始化列表中的顺序是不相关的。

Gee。我必须是
而不是
门。:)更是如此,因为他调用的是
pBuilder->GetLogger()
,而不是
p\u Builder->GetLogger()
。两者都是合法的,但第二个对类定义中被重新排序的实例变量很敏感。@Eclipse:哦,我甚至没有看到ha@你的意思是使用成员或参数吗?两种方法都是安全的。那么在构造函数体中赋值和在参数列表中赋值有什么区别呢?除了能够分配给
const
成员之外?@Martin:Close;它们按照它们在类定义中出现的顺序进行初始化。初始值设定项列表应该与之匹配,但严格地说,它不必匹配。如果您建议的是从构造函数调用的私有
init
函数,我不太在乎,但我想这是可以的。如果您建议的是必须由类的用户调用的公共
init
函数,则该函数容易出错和不一致(创建对象后,它将处于无效状态,用户可能忘记调用
init
或尝试在构造和初始化之间使用该对象…)可以使用伪成员,并让init方法返回类型。例如
类IDGenerator{public:IDGenerator();bool reset();std::uint32_t generate();private:bool mReset;t_ID_set mIds;std::uint32_t mId;};IDGenerator::IDGenerator():mReset(reset()){}bool IDGenerator::reset(){mIds.clear();mId=0;返回true;}
class PluginLoader
{
   public:
      Logger* const p_Logger;   // p_Logger is listed first before p_Builder
      Builder* const p_Builder;

      //Others
};

PluginLoader::PluginLoader(Builder* const pBuilder)
   :p_Builder(pBuilder),
    p_Logger(p_Builder->GetLogger())   // Though listed 2nd, it is called first.
                                       // This wouldn't be a problem if pBuilder 
                                       // was used instead of p_Builder
{
   //Stuff
}