具有类内初始化的默认默认构造函数的行为是什么?

时间:2014-10-03 16:12:26

标签: c++ c++11

假设以下内容:

class foo
{
public:
  foo() = default;

private:
  std::string m_str = "Hello";
};

我无法找到有关cppreference.com或C ++ 11草案的任何文档,它解释了默认构造函数在这里对m_str执行的操作。我自然的假设是编译器足够智能,如果它已经在类中初始化,则不能在默认构造函数中初始化m_str,但也许我错了。

有人能在这里解释初始化行为吗?任何保证还是未指明?

2 个答案:

答案 0 :(得分:11)

这是在[class.ctor] / 5中明确定义和指定的:

  

[...]隐式定义的默认构造函数执行该类的初始化集合,该初始化集合将由该用户编写的默认构造函数执行,该类没有ctor-initializer(12.6.2)和一个空复合-声明。 [...]

因此默认构造函数执行与以下相同的操作:

foo() {}

这反过来又适用于每个数据成员(参见[class.base.init] / 8)。

答案 1 :(得分:4)

您用于m_str的初始化形式被标准称为 brace-or-equal-initializer

初始化者下的第一段中,标准声明:

  

8.5感兴趣者

     

1声明者可以为声明的标识符指定初始值。标识符指定要初始化的变量。 8.5的其余部分中描述的初始化过程也适用于其他语法上下文指定的初始化,例如使用argumentsmet表达式(5.2.2)初始化函数参数或初始化返回值(6.6.3)。


        initializer:
            brace-or-equal-initializer
            ( expression-list )
        brace-or-equal-initializer:
            = initializer-clause
            braced-init-list

关于班级成员的部分......

  

9.2班级成员

     

5可以使用大括号或等号初始值来初始化成员。

在关于初始化基础和成员的部分......

  

12.6.2初始化基础和成员

     

8在非委托构造函数中,如果给定的非静态数据成员或基类未由mem-initializer-id指定(包括没有mem-initializer-list的情况,因为构造函数没有ctor-initializer)并且实体不是抽象类的虚拟基类(10.4),然后是

     

- 如果实体是具有大括号或等于初始化程序的非静态数据成员,则实体初始化为8.5中指定

来到你的班级,

foo() = default;

相当于:

foo(){}

当使用没有成员初始化列表的默认构造函数时,默认初始化成员数据。在默认初始化过程中,对于具有大括号或等于初始化程序的成员,该表单用于初始化它们。在你的情况下,

foo(){}

相当于:

foo() : m_str("Hello") {}