使用成员初始值设定项列表会使初始化速度稍快

Will using a member initializer list make the initialization slightly faster?

本文关键字:列表 初始化 速度 成员      更新时间:2023-10-16

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 的情况下,默认初始化不执行任何操作。

我希望大多数编译器在您的两个示例中都生成相同的代码。这没有任何区别。