C++ 构造函数中这种奇怪的冒号成员(“:”)语法是什么?

C++ 构造函数中这种奇怪的冒号成员(“:”)语法是什么?,c++,syntax,constructor,c++-faq,ctor-initializer,C++,Syntax,Constructor,C++ Faq,Ctor Initializer,最近我看到了如下示例: #include <iostream> class Foo { public: int bar; Foo(int num): bar(num) {}; }; int main(void) { std::cout << Foo(42).bar << std::endl; return 0; } #包括 福班{ 公众: int-bar; Foo(intnum):bar(num){}; }; 内部主(空){ std::c

最近我看到了如下示例:

#include <iostream>

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

int main(void) {
  std::cout << Foo(42).bar << std::endl;
  return 0;
}
#包括
福班{
公众:
int-bar;
Foo(intnum):bar(num){};
};
内部主(空){
std::cout这是一个成员初始化列表。您应该在任何目录中找到有关它的信息

(但是,请注意FAQ条目末尾列出的例外情况)

FAQ条目的要点是

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

这是一个成员初始化列表。您应该在任何

(但是,请注意FAQ条目末尾列出的例外情况)

FAQ条目的要点是

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


你是对的,这确实是一种初始化成员变量的方法。我不确定这是否有什么好处,除了清楚地表示这是一种初始化。使用“bar=num”代码内部可能更容易被移动、删除或误解。

您是对的,这确实是一种初始化成员变量的方法。我不确定这有什么好处,除了清楚地表示这是一种初始化。使用“bar=num”代码内部可能更容易被移动、删除或误解。

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

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

这是构造函数初始化。这是初始化类构造函数中成员的正确方法,因为它防止调用默认构造函数

考虑以下两个例子:

// Example 1
Foo(Bar b)
{
   bar = b;
}

// Example 2
Foo(Bar b)
   : bar(b)
{
}
在示例1中:

Bar bar;  // default constructor
bar = b;  // assignment
在示例2中:

Bar bar(b) // copy constructor

这都是关于效率的。

这是构造函数初始化。初始化类构造函数中的成员是正确的方法,因为它可以防止调用默认构造函数

考虑以下两个例子:

// Example 1
Foo(Bar b)
{
   bar = b;
}

// Example 2
Foo(Bar b)
   : bar(b)
{
}
在示例1中:

Bar bar;  // default constructor
bar = b;  // assignment
在示例2中:

Bar bar(b) // copy constructor

这一切都是为了提高效率。

这称为初始化列表。这是初始化类成员的一种方法。使用它比简单地在构造函数体中为成员分配新值有好处,但如果您有常量或引用的类成员,则必须对其进行初始化。

这称为初始化列表。这是初始化类成员的一种方法。使用它比简单地在构造函数体中为成员分配新值有好处,但如果类成员是常量或引用,则必须初始化它们。

这是一个初始化列表。它将在或者运行构造函数主体。 考虑

vs

在第一个示例中,str将由其无参数构造函数初始化

string();
string( const string& s );
在Foo构造函数的主体之前

string& operator=( const string& s );
将像调用str=p一样调用“str”

在第二个示例中,str将由 调用其构造函数

string();
string( const string& s );

以“p”作为参数。

这是一个初始化列表。它将在运行构造函数主体之前初始化成员。 考虑

vs

在第一个示例中,str将由其无参数构造函数初始化

string();
string( const string& s );
在Foo构造函数的主体之前

string& operator=( const string& s );
将像调用str=p一样调用“str”

在第二个示例中,str将由 调用其构造函数

string();
string( const string& s );

以“p”作为参数。

还有另一个“好处”


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

还有另一个“好处”


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

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

<>我想注意的是,正如你所说的,语法看起来像是构造函数调用,不一定是构造函数调用。在C++语言中,<>代码>(/>代码>语法只是初始化语法的一种标准形式。对于不同的类型,它的解释是不同的。对于具有用户定义的构造函数的类类型,它意味着一件事。(它实际上是一个构造函数调用),对于没有用户定义构造函数的类类型,它意味着另一件事(所谓的)空
()
),而对于非类类型,它又意味着另一件事(因为非类类型没有构造函数)


在您的情况下,数据成员的类型为
int
int
不是类类型,因此它没有构造函数。对于类型
int
,此语法仅表示“使用
num
的值初始化
bar
”就是这样。直接这样做,不涉及构造函数,因为,
int
不是的类类型,因此它不能有任何构造函数。

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