C++ 通过分配其他构造函数初始化的类成员来初始化类成员是一个坏主意吗?

Posted

技术标签:

【中文标题】C++ 通过分配其他构造函数初始化的类成员来初始化类成员是一个坏主意吗?【英文标题】:C++ Is it a bad idea to initialise class members by assigning them other constructor initialised class members? 【发布时间】:2021-09-16 20:15:46 【问题描述】:

我发现了一种初始化类成员 q 的查询方法,方法是将其分配给通过构造函数 i 初始化的不同类成员:

class test
public:
    test(int c) : i(c) 
    

    int i;
    int q = i;
;

int main() 
    std::cout << test(1).q << std::endl; //outputs 1

但是,如果我交换 iq 的声明顺序:

int q = i;
int i;

打印出i 输出0。

以这种方式初始化类成员是不是一个坏主意?显然,在这个例子中,将: i(c), q(c) 添加到构造函数中可能更容易。

但是对于存在依赖i 的类成员的情况,例如某些对象的构造函数采用int (i) 并具有私有= 运算符和复制构造函数,这种方法可能是初始化该对象的好方法吗?或者这是一个坏主意,应该始终避免?

【问题讨论】:

成员按照定义的顺序进行初始化。即使你在成员初始化列表中: q(c), i(c),如果i先定义,i会先初始化。没有例外。它们也会以相反的顺序被销毁,没有例外,所以你有可靠的行为保证。 是的,这是个坏主意。如您所见,只需有人移动变量的顺序,现在代码就不起作用了。 从技术上讲,您可以依赖int i; int q = i;,但正如您所展示的那样,它很容易损坏。我建议不要这样做,但最终这可能是一个见仁见智的问题。 对于情况 (2) 提高编译器警告级别 - 实时 - godbolt.org/z/e6Mv1hhTz 【参考方案1】:

是的,您已经概述了失败的条件。不难想象有人由于重新排序而无意中破坏了您的代码。

如果你想做这样的事情,最好在输入源的构造函数中分配两者。

test(int c) : q(c), i(c) 

这减少了初始化顺序的混淆,两个变量不再相互依赖。

【讨论】:

以上是关于C++ 通过分配其他构造函数初始化的类成员来初始化类成员是一个坏主意吗?的主要内容,如果未能解决你的问题,请参考以下文章

运行时在构造函数中初始化向量类成员——C++

C++ 初始化作为对象指针容器的成员变量

在构造函数代码之前禁用默认类成员初始化

如何在构造函数中初始化 C++ 对象成员变量?

在 C++ 中初始化动态二维数组

构造函数和初始化列表