Bjarne Stroustrup在他的书"使用C++的编程,原理和实践"中介绍了成员初始值设定项列表的概念,第314-316页(§ 9.4.4)。他使用以下示例:
// Simple Date (year, month, day)
class Date
{
public:
Date(int yy, int mm, int dd): y{yy}, m{mm}, d{dd}
{
//...
}
private:
int y, m, d;
};
在第315页,他说:
我们可以写:
Date::Date(int yy, int mm, int dd) // constructor { y = yy; m = mm; d = dd; }
但是,原则上我们首先默认初始化成员,然后为它们赋值。
因此,我是否可以得出结论,使用成员初始值设定项列表会使代码稍微快一点?当然,在现代PC上没有人会注意到。但我打算使用C++进行嵌入式开发。
编辑:
我将进一步说明我的问题。我所说的"稍快"实际上是指"涉及的 CPU 周期更少"。
我也同意,这个特定示例的潜在效率提升将几乎为零。但是对于更大的类和结构,它可能在微控制器上变得引人注目。
在第二个示例中,您没有初始化,而是分配给已经初始化的变量。变量在进入构造函数之前被初始化(默认构造),因此您实际上设置了它们两次。
int
没有任何特定的默认初始值设定项,因此您不会注意到,但请尝试使用不同的代码,如
#include <iostream>
using namespace std;
class Foo
{
int x;
public:
Foo() : x(0) { cout << "Foo()" << endl; }
Foo(int x) : x(x) { cout << "Foo(int)" << endl; }
Foo& operator=(const Foo& o) {
cout << "Foo::operator=(const Foo&)" << endl;
this->x = o.x; return *this;
}
};
class Bar
{
Foo foo;
public:
Bar(const Foo& foo) { this->foo = foo; }
Bar(bool, const Foo& foo) : foo(foo) { }
};
int main() {
cout << "Assigned in constructor" << endl;
Bar bar = Bar(Foo(5));
cout << "Assigned in initializer list" << endl;
Bar bar2 = Bar(false, Foo(5));
}
这打印
Assigned in constructor
Foo(int)
Foo()
Foo::operator=(const Foo&)
Assigned in initializer list
Foo(int)
所以你看它们绝对不是等价的。实际上,例如,您无法在构造函数中分配const
字段
C++ 标准指定"默认初始化",如下所示:
[dcl.init]
默认初始化 T 类型的对象意味着:
— 如果 T 是 (可能符合 cv 条件)类类型(第 9 条),默认值 调用 T 的构造函数 (12.1)(初始化为 如果 T 没有默认构造函数或重载解析,则格式不正确 (13.3) 导致歧义或功能被删除或 无法从初始化上下文中访问);
— 如果 T 是 数组类型,每个元素都是默认初始化的;
— 否则,不执行初始化。
你的班级成员是朴素的,花园般的,int
s。它们不是类。它们不是数组。因此,在 int
s 的情况下,默认初始化不执行任何操作。
我希望大多数编译器在您的两个示例中都生成相同的代码。这没有任何区别。