初始化列表将始终在构造函数代码之前处理吗? [英] Will the initialization list always be processed before the constructor code?

查看:112
本文介绍了初始化列表将始终在构造函数代码之前处理吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

初始化列表将始终在构造函数代码之前处理吗?

Will the initialization list always be processed before the constructor code?

换句话说,以下代码将始终打印< unknown> ,并且构造的类将以作为 source _ 的值(如果全局变量 something true )?

In other words, will the following code always print <unknown>, and the constructed class will have "known" as value for source_ (if the global variable something is true)?

class Foo {
  std::string source_;
public:
  Foo() : source_("<unknown>") {
    std::cout << source_ << std::endl;
    if(something){
      source_ = "known";
    }
  }
};


推荐答案

是的,按照 C ++ 11:12.6.2 /10C++1415.6.2中的同一部分/ 13 C ++ 17 中):

Yes, it will, as per C++11: 12.6.2 /10 (same section in C++14, 15.6.2 /13 in C++17):

在非委托的构造函数中,初始化按以下顺序进行(我的粗体):

In a non-delegating constructor, initialization proceeds in the following order (my bold):


  • 首先,并且仅对于最派生类(1.8)的构造函数,虚拟基类按照它们在基类的有向无环图的深度优先从左到右遍历时出现的顺序进行初始化,其中从左到右正确是基类在派生类base-specifier-list中的出现顺序。

  • First, and only for the constructor of the most derived class (1.8), virtual base classes are initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where "left-to-right" is the order of appearance of the base classes in the derived class base-specifier-list.

然后,直接基类按声明顺序初始化为它们会出现在base-specifier-list中(与mem-initializer的顺序无关)。

Then, direct base classes are initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).

然后,非静态数据成员将在在类定义中声明它们的顺序(再次考虑)

Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).

最后, 的复合语句

Finally, the compound-statement of the constructor body is executed.

使用init的主要原因-lists是为了帮助编译器优化。通常,非基本类型的初始化列表(即类对象而不是 int float 等)

The main reason for using init-lists is to help the compiler with optimisation. Init-lists for non-basic types (i.e., class objects rather than int, float, etc.) can generally be constructed in-place.

如果创建对象然后在构造函数中分配给它,通常会导致临时对象的创建和销毁,这是低效的。

If you create the object then assign to it in the constructor, this generally results in the creation and destruction of temporary objects, which is inefficient.

初始化列表可以避免这种情况(当然,如果编译器可以做到这一点,但大多数应该这样做)。

Init-lists can avoid this (if the compiler is up to it, of course but most of them should be).

下面的完整程序将输出7,但这是针对特定的编译器(CygWin g ++)的,因此它不能保证行为比原始问题中的示例还要多。

The following complete program will output 7 but this is for a specific compiler (CygWin g++) so it doesn't guarantee that behaviour any more than the sample in the original question.

但是,按照上面第一段中的引用,标准确实可以做到。

However, as per the citation in the first paragraph above, the standard does actually guarantee it.

#include <iostream>
class Foo {
    int x;
    public:
        Foo(): x(7) {
            std::cout << x << std::endl;
        }
};
int main (void) {
    Foo foo;
    return 0;
}

这篇关于初始化列表将始终在构造函数代码之前处理吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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