使用成员初始化器列表会使初始化速度稍微快一些吗?
Will using a member initializer list make the initialization slightly faster?
Bjarne Stroustrup 在他的书 "Programming, Principles and practices using 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 页他说:
We could have written:
Date::Date(int yy, int mm, int dd) // constructor
{
y = yy;
m = mm;
d = dd;
}
but then we would in principle first have default initialized the members and then assigned values to them.
因此,我是否可以得出结论,使用 成员初始值设定项列表 可以使代码稍微快一些?当然,在现代 PC 上没有人会注意到。但是我打算用C++做嵌入式开发。
编辑:
我会进一步说明我的问题。 "slightly faster" 我实际上是指 "less CPU cycles involved".
我也同意这个特定示例的潜在效率提升几乎为零。但是对于更大的 类 和结构,它可能会在微控制器上变得明显。
C++标准规定"default initialization"如下:
[dcl.init]
To default-initialize an object of type T means:
— if T is
a (possibly cv-qualified) class type (Clause 9), the default
constructor (12.1) for T is called (and the initialization is
ill-formed if T has no default constructor or overload resolution
(13.3) results in an ambiguity or in a function that is deleted or
inaccessible from the context of the initialization);
— if T is an
array type, each element is default-initialized;
— otherwise, no initialization is performed.
您的 class 成员是普通的普通人 int
。它们不是 classes。它们不是数组。因此,在 int
s 的情况下,默认初始化什么都不做。
我希望大多数编译器在您的两个示例中生成相同的代码。无论如何,这没有什么区别。
在第二个例子中,你没有初始化,你赋值给已经初始化的变量。变量在进入构造函数之前被初始化(默认构造),所以你实际上是在设置它们两次。
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
字段
Bjarne Stroustrup 在他的书 "Programming, Principles and practices using 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 页他说:
We could have written:
Date::Date(int yy, int mm, int dd) // constructor { y = yy; m = mm; d = dd; }
but then we would in principle first have default initialized the members and then assigned values to them.
因此,我是否可以得出结论,使用 成员初始值设定项列表 可以使代码稍微快一些?当然,在现代 PC 上没有人会注意到。但是我打算用C++做嵌入式开发。
编辑:
我会进一步说明我的问题。 "slightly faster" 我实际上是指 "less CPU cycles involved".
我也同意这个特定示例的潜在效率提升几乎为零。但是对于更大的 类 和结构,它可能会在微控制器上变得明显。
C++标准规定"default initialization"如下:
[dcl.init]
To default-initialize an object of type T means:
— if T is a (possibly cv-qualified) class type (Clause 9), the default constructor (12.1) for T is called (and the initialization is ill-formed if T has no default constructor or overload resolution (13.3) results in an ambiguity or in a function that is deleted or inaccessible from the context of the initialization);
— if T is an array type, each element is default-initialized;
— otherwise, no initialization is performed.
您的 class 成员是普通的普通人 int
。它们不是 classes。它们不是数组。因此,在 int
s 的情况下,默认初始化什么都不做。
我希望大多数编译器在您的两个示例中生成相同的代码。无论如何,这没有什么区别。
在第二个例子中,你没有初始化,你赋值给已经初始化的变量。变量在进入构造函数之前被初始化(默认构造),所以你实际上是在设置它们两次。
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
字段