【发布时间】:2010-12-08 14:39:00
【问题描述】:
我知道使用初始化列表的好处是,它们在初始化非内置类成员时提供了效率。例如,
Fred::Fred() : x_(whatever) { }
优于,
Fred::Fred() { x_ = whatever; }
如果 x 是自定义类的对象。除此之外,为了保持一致性,这种风格甚至与内置类型一起使用。
这样做最常见的好处是提高了性能。如果表达式whatever 与成员变量x_ 的类型相同,则whatever 表达式的结果直接在x_ 内部构造——编译器不会制作对象的单独副本。
对于另一种风格,表达式whatever 会导致创建一个单独的临时对象,并将这个临时对象传递给x_ 对象的赋值运算符。然后该临时对象在 ; 处被破坏。那是低效的。
问题
在以下示例中使用初始化列表是否有任何效率提升。
我认为没有收获。第一个版本调用字符串的复制构造函数,另一个调用字符串的赋值运算符(没有创建任何临时的)。对吗?
class MyClass
{
public:
MyClass(string n):name(n) { }
private:
string name;
};
class MyClass
{
public:
MyClass(string n)
{
name=n;
}
private:
string name;
};
【问题讨论】:
-
初始化列表的另一个好处(如果你想称之为好处)是它们是初始化某些事物的唯一方法 - 使用非默认 ctor、const 成员和参考成员。
-
另外,如果您担心性能,我宁愿使用 'const&' 来传递参数,而不是复制。
-
你怎么会有
Fred::Fred() : x_(whatever)?弗雷德不接受任何论据。 -
在 Visual Studio 2017 专业版“内存视图”中很容易看到内存地址看起来不同,因此在此证伪了所有错误假设。事实上,我开始明白类初始化列表的真正目的是为了
const,而不是为了速度。