最近我看到了这样一个例子:

#include <iostream>

class Foo {
public:
  int bar;
  Foo(int num): bar(num) {};
};

int main(void) {
  std::cout << Foo(42).bar << std::endl;
  return 0;
}

这个奇怪的bar(num)是什么意思?它似乎初始化了成员变量,但我以前从未见过这种语法。它看起来像一个函数/构造函数调用,但int?这对我来说毫无意义。也许有人能启发我。顺便问一下,还有没有其他像这样深奥的语言特性,你在普通的c++书中找不到?


当前回答

另一个已经向您解释过,您观察到的语法称为“构造函数初始化列表”。此语法允许自定义初始化类的基子对象和成员子对象(而不是允许它们默认初始化或保持未初始化)。

I just want to note that the syntax that, as you said, "looks like a constructor call", is not necessarily a constructor call. In C++ language the () syntax is just one standard form of initialization syntax. It is interpreted differently for different types. For class types with user-defined constructor it means one thing (it is indeed a constructor call), for class types without user-defined constructor it means another thing (so called value initialization ) for empty ()) and for non-class types it again means something different (since non-class types have no constructors).

在本例中,数据成员的类型为int。Int不是类类型,所以它没有构造函数。对于int类型,此语法仅意味着“用num值初始化bar”,仅此而已。它就是这样直接完成的,不涉及构造函数,因为int不是类类型,因此它不能有任何构造函数。

其他回答

另一个已经向您解释过,您观察到的语法称为“构造函数初始化列表”。此语法允许自定义初始化类的基子对象和成员子对象(而不是允许它们默认初始化或保持未初始化)。

I just want to note that the syntax that, as you said, "looks like a constructor call", is not necessarily a constructor call. In C++ language the () syntax is just one standard form of initialization syntax. It is interpreted differently for different types. For class types with user-defined constructor it means one thing (it is indeed a constructor call), for class types without user-defined constructor it means another thing (so called value initialization ) for empty ()) and for non-class types it again means something different (since non-class types have no constructors).

在本例中,数据成员的类型为int。Int不是类类型,所以它没有构造函数。对于int类型,此语法仅意味着“用num值初始化bar”,仅此而已。它就是这样直接完成的,不涉及构造函数,因为int不是类类型,因此它不能有任何构造函数。

我不知道你怎么会错过这个,这是非常基本的。这是初始化成员变量或基类构造函数的语法。它既适用于普通的旧数据类型,也适用于类对象。

在这个线程中还没有提到:从c++ 11开始,成员初始化器列表可以使用list-initialization(又名list-initialization)。“统一初始化”,“带括号初始化”):

Foo(int num): bar{num} {}

它与其他上下文中的列表初始化具有相同的语义。

还有一个“好处”

如果成员变量类型不支持空初始化,或者它是一个引用(不能被空初始化),那么你别无选择,只能提供一个初始化列表

它是一个成员初始化列表。你可以在任何好的c++书籍中找到有关它的信息。

在大多数情况下,您应该初始化成员初始化列表中的所有成员对象(但是,请注意FAQ条目末尾列出的例外)。

常见问题解答的要点是,

在其他条件相同的情况下,如果使用初始化列表而不是赋值,代码将运行得更快。