在他的“使用C ++进行编程,原理和实践”一书中,Bjarne Stroustrup在第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周期”
我也同意这个特定例子的潜在效率提升几乎为零。但是对于更大的类和结构,它可能在微控制器上变得明显。
答案 0 :(得分:5)
在第二个示例中,您没有初始化,您正在分配已经初始化的变量。在进入构造函数之前,变量已初始化(默认构造),因此实际上是将它们设置两次。
int
没有任何特定的默认初始值设定项,因此您不会注意到但尝试使用不同的代码as in
#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
字段
答案 1 :(得分:1)
C ++标准指定“默认初始化”如下:
[dcl.init]
默认初始化T类型的对象意味着:
- 如果T是 一个(可能是cv限定的)类类型(第9节),默认值 调用T的构造函数(12.1)(初始化为 如果T没有默认构造函数或重载决策,则格式错误 (13.3)导致歧义或被删除的函数或 从初始化的上下文中无法访问);
- 如果T是 数组类型,每个元素都是默认初始化的;
- 否则,不执行初始化。
你的班级成员是朴素的,花园式的,int
。他们不是班级。它们不是数组。因此,在int
s的情况下,默认初始化不执行任何操作。
我希望大多数编译器都能在两个示例中生成相同的代码。无论如何都没有区别。