其他分享
首页 > 其他分享> > c – 派生类初始化列表中调用基类构造函数的顺序

c – 派生类初始化列表中调用基类构造函数的顺序

作者:互联网

struct B { int b1, b2;  B(int, int); };
struct D : B {
  int d1, d2;
// which is technically better ?
  D (int i, int j, int k, int l) : B(i,j), d1(k), d2(l) {} // 1st Base
// or
  D (int i, int j, int k, int l) : d1(k), d2(l), B(i,j) {} // last Base
};

以上只是伪代码.实际上我想知道调用基础构造函数的顺序是否重要?
是否有任何不良行为(特别是拐角案件)由任何案件引起?我的问题是更多的技术方面,而不是编码风格.

解决方法:

您在问题中引用的顺序不是“调用基础构造函数的顺序”.实际上,你不能调用构造函数.构造函数不能由用户调用.只有编译器可以调用构造函数.

你可以做的是指定初始化器.在这种情况下(构造函数初始化列表),您要为某个较大对象的子对象指定初始值设定项.指定这些初始值设定项的顺序无关紧要:编译器将按照语言规范定义的非常特定的顺序调用构造函数,而不管指定初始值设定项的顺序如何.始终首先调用基类构造函数(按照类定义中列出基类的顺序),然​​后调用成员子对象的构造函数(同样,按照类定义中列出这些成员的顺序).

(当涉及到虚拟基类时,这条规则有一些特点,但我决定不在这里包含它们.)

至于不良行为……当然,这里存在潜在的“不良行为”.如果你假设初始化的顺序取决于你在构造函数初始化程序列表中使用的顺序,当你发现编译器完全忽略该顺序并使用它自己的顺序时,你很可能最终会遇到令人不快的意外(顺序)声明)而不是.例如,此代码的作者

struct S {
  int b, a;
  S() : a(5), b(a) {}
};

可能期望a首先被初始化,而b从a接收初始值5,但实际上这不会发生,因为b在a之前被初始化.

标签:base-class,c,constructor,initialization-list
来源: https://codeday.me/bug/20190926/1818930.html