初始化列表的好处

发布于 2024-08-07 22:57:40 字数 715 浏览 9 评论 0 原文

据我所知,使用初始化列表的好处是,它们在初始化非内置类成员时提供了效率。例如,

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;
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

我纯我任性 2024-08-14 22:57:40

第二个版本是调用 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?-)

吃不饱 2024-08-14 22:57:40

我认为初始化常量数据成员的唯一方法是在初始化列表中,

例如。在标头中:

class C
{
    C();
private:
    const int x;
    int y;
}

在 cpp 文件中:

C::C() :
    x( 10 ),
    y( 10 )
{
    x = 20; // fails
    y = 20;
}

I think the only way to initialize const data members is in the initialization list

Eg. in the header:

class C
{
    C();
private:
    const int x;
    int y;
}

And the in the cpp file:

C::C() :
    x( 10 ),
    y( 10 )
{
    x = 20; // fails
    y = 20;
}
狂之美人 2024-08-14 22:57:40

请记住,复制构造函数和赋值运算符之间存在明显的区别:

  • 复制构造函数使用其他实例作为获取初始化信息的位置来构造新对象。
  • 赋值运算符修改已完全构造的现有对象(即使仅使用默认构造函数)

因此在第二个示例中,此时已经完成了一些创建 name 的工作就

 name=n;

达到了。

然而,很有可能(特别是在这个简单的示例中)所做的工作非常小(可能只是将 string 对象中的一些数据成员清零),并且工作在优化后的过程中被完全优化掉了。建造。但只要有可能,使用初始值设定项列表仍然被认为是一种良好的形式。

Remember that there is a distinct difference between a copy constructor and an assignment operator:

  • the copy ctor constructs a new object using some other instance as a place to get initialization information from.
  • the assignment operator modifies an already existing object that has already been fully constructed (even if it's only by using a default constructor)

So in your second example, some work has already been done to create name by the time that

 name=n;

is 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.

情定在深秋 2024-08-14 22:57:40

这是初始化成员的好方法:

  • const
  • 没有默认构造函数(它是私有的)

It's a great way to initialize members that :

  • are const
  • don't have a default constructor (it's private)
我们的影子 2024-08-14 22:57:40

我们还可以执行 构造函数委托通过初始化列表。

We can also perform the constructor delegation via the initialization list.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文