首先,让我解释一下mem-initializer-list是什么。一个mem-initializer-list是一个逗号分隔的mem-initializer列表,其中每个mem-initializer是一个成员名称(
,后跟一个 ,然后是一个表达式列表,然后是一个)
。表达式列表是成员的构造方式。例如,在
static const char s_str[] = "bodacydo";
class Example
{
private:
int *ptr;
string name;
string *pname;
string &rname;
const string &crname;
int age;
public:
Example()
: name(s_str, s_str + 8), rname(name), crname(name), age(-4)
{
}
};
用户提供的无参数构造函数的mem-initializer-list是name(s_str, s_str + 8), rname(name), crname(name), age(-4)
. 这个mem-initializer-list意味着name
成员由接受两个输入迭代器的std::string
构造函数初始化,rname
成员使用对 的引用进行初始化name
,crname
成员使用对 的常量引用进行初始化name
,age
成员使用值进行初始化-4
。
每个构造函数都有自己的mem-initializer-list,并且成员只能按照规定的顺序进行初始化(基本上是在类中声明成员的顺序)。因此, 的成员Example
只能按以下顺序初始化:ptr
、name
、pname
、rname
、crname
和age
。
当您不指定成员的mem-initializer时,C++ 标准说:
如果实体是类类型的非静态数据成员 ...,则该实体是默认初始化的 (8.5)。...否则,实体未初始化。
在这里,因为name
是类类型的非静态数据成员,所以如果name
在mem-initializer-list中没有指定初始化器,则它是默认初始化的。的所有其他成员Example
都没有类类型,因此它们没有被初始化。
当标准说它们没有被初始化时,这意味着它们可以有任何值。因此,因为上面的代码没有初始化pname
,它可以是任何东西。
请注意,您仍然必须遵循其他规则,例如必须始终初始化引用的规则。不初始化引用是编译器错误。