据我所知,使用初始化列表的好处是,它们在初始化非内置类成员时提供了效率。例如,
Fred::Fred() : x_(whatever) { }
优于
Fred::Fred() { x_ =whatever; }
如果 x 是自定义类的对象。除此之外,为了保持一致性,这种样式甚至与内置类型一起使用。
这样做最常见的好处是提高性能。如果表达式whatever 与成员变量x_ 类型相同,则whatever 表达式的结果将直接在x_ 内部构造——编译器不会创建该对象的单独副本。
对于另一种样式,表达式无论什么都会导致创建一个单独的临时对象,并且该临时对象被传递到 x_ 对象的赋值运算符中。然后该临时对象在;处被破坏。那是低效的。
问题
在以下示例中使用初始化列表是否会提高效率?
我认为没有任何收获。第一个版本调用字符串的复制构造函数,另一个版本调用字符串的赋值运算符(没有创建任何临时的)。是这样正确的吗?
class MyClass
{
public:
MyClass(string n):name(n) { }
private:
string name;
};
class MyClass
{
public:
MyClass(string n)
{
name=n;
}
private:
string name;
};
Of what I know of benefits of using initialization list is that they provide efficiency when initializing class members which are not build-in. For example,
Fred::Fred() : x_(whatever) { }
is preferable to,
Fred::Fred() { x_ = whatever; }
if x is an object of a custom class. Other than that, this style is used even with built-in types for the sake of consistency.
The most common benefit of doing this is improved performance. If the expression whatever is the same type as member variable x_, the result of the whatever expression is constructed directly inside x_ — the compiler does not make a separate copy of the object.
With the other style, the expression whatever causes a separate, temporary object to be created, and this temporary object is passed into the x_ object's assignment operator. Then that temporary object is destructed at the ;. That's inefficient.
Question
Is there any efficiency gain in the following example with using initialization list.
I think there is no gain. The first version calls string's copy constructor and the other calls string's assignment operator (there isn't any temporary thats created). It that correct?
class MyClass
{
public:
MyClass(string n):name(n) { }
private:
string name;
};
class MyClass
{
public:
MyClass(string n)
{
name=n;
}
private:
string name;
};
发布评论
评论(5)
第二个版本是调用 string 的默认构造函数,然后调用 string 的复制赋值运算符——与第一个版本相比,肯定会存在(较小的)效率损失,第一个版本直接调用 c 的复制构造函数(例如,根据 string 的实现,可能会有无用的分配然后释放一些微小的结构)。为什么不总是使用正确的方法呢?-)
The second version is calling string's default ctor and then string's copy-assignment operator -- there could definitely be (minor) efficiency losses compared to the first one, which directly calls c's copy-ctor (e.g., depending on string's implementation, there might be useless allocation-then-release of some tiny structure). Why not just always use the right way?-)
我认为初始化常量数据成员的唯一方法是在初始化列表中,
例如。在标头中:
在 cpp 文件中:
I think the only way to initialize const data members is in the initialization list
Eg. in the header:
And the in the cpp file:
请记住,复制构造函数和赋值运算符之间存在明显的区别:
因此在第二个示例中,此时已经完成了一些创建
name
的工作就达到了。
然而,很有可能(特别是在这个简单的示例中)所做的工作非常小(可能只是将 string 对象中的一些数据成员清零),并且工作在优化后的过程中被完全优化掉了。建造。但只要有可能,使用初始值设定项列表仍然被认为是一种良好的形式。
Remember that there is a distinct difference between a copy constructor and an assignment operator:
So in your second example, some work has already been done to create
name
by the time thatis reached.
However, it's quite possible (especially in this simple example) that the work done is vanishingly small (probably just zeroing out some data members in the
string
object) and that the work is optimized away altogether in an optimized build. but it's still considered good form to use initializer lists whenever possible.这是初始化成员的好方法:
It's a great way to initialize members that :
我们还可以执行 构造函数委托通过初始化列表。
We can also perform the constructor delegation via the initialization list.