从派生类初始化列表调用基类构造函数的顺序 [英] Order of calling base class constructor from derived class initialization list

查看:426
本文介绍了从派生类初始化列表调用基类构造函数的顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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
};

以上只是伪代码。实际上我想知道调用基础构造函数的顺序是否重要?
是否有任何坏行为(特别是 )造成的任何情况?

Above is just pseudo code. In actual I wanted to know that does the order of calling base constructor matter ? Are there any bad behaviors (especially corner cases) caused by any of the cases ? My question is on more technical aspect and not on coding styles.

推荐答案

我们的问题是关于编码风格的 你的问题不是调用基础构造函数的顺序。实际上,你不能调用构造函数。构造函数不能由用户调用。只有编译器可以调用构造函数。

The order you refer in your question is not the "order of calling base constructor". In fact, you can't call a constructor. Constructors are not callable by the user. Only compiler can call constructors.

你可以做的是指定初始化器。在这种情况下(构造函数初始化器列表),您正在为一些较大对象的子对象指定初始化器。您指定这些初始化程序的顺序无关紧要:编译器将以语言规范定义的非常特定的顺序调用构造函数,而不考虑您指定初始化程序的顺序。基类构造函数总是被称为第一类(在类定义中列出的基类的顺序),然​​后调用成员子对象的构造函数(同样,按照类定义中列出这些成员的顺序)。

What you can do is to specify initializers. In this case (constructor initializer list) you are specifying initializers for subobjects of some larger object. The order in which you specify these initializers does not matter: the compiler will call the constructors in a very specific order defined by the language specification, regardless of the order in which you specify the initializers. The base class constructors are always called first (in the order in which the base classes are listed in class definition), then the constructors of member subobjects are called (again, in the order in which these members are listed in the class definition).

(这个规则在虚拟基础类中有一些特殊性,但我决定不在这里。)

(There are some peculiarities in this rule when it comes to virtual base classes, but I decided not to include them here.)

对于不良行为...当然,这里有一个潜在的坏行为。如果你假设初始化的顺序取决于你在构造函数初始化器列表中使用的顺序,当你发现编译器完全忽略了这个顺序并使用它自己的顺序(顺序)时,你最有可能遇到一个令人不愉快的惊喜,声明)。例如,此代码的作者

As for the bad behaviors... Of course there is a potential for "bad behaviors" here. If you assume that the order of initialization depends on the order you used in the constructor initializer list, you will most likely eventually run into an unpleasant surprise, when you discover that the compiler completely ignores that order and uses its own order (the order of declaration) instead. For example, the author of this code

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

可能希望先初始化 a b a 接收 5 的初始值,但实际上这不会发生,因为 b a 之前初始化。

might expect a to be initialized first, and b to receive the initial value of 5 from a, but in reality this won't happen since b is initialized before a.

这篇关于从派生类初始化列表调用基类构造函数的顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆