13

今天注意到一个同事的一些代码,它在初始化时初始化了类变量。然而,它引起了警告,他说,因为它们的顺序。我的问题是为什么最好在当前位置而不是在大括号内进行变量初始化?

DiagramScene::DiagramScene( int slideNo, QRectF screenRect, MainWindow* parent )
    : QGraphicsScene( screenRect, parent ),
    myParent( parent ), 
    slideUndoImageCurrentIndex(-1),
    nextGroupID(0),
    m_undoInProgress(false),
    m_deleteItemOnNextUndo(0)
    line(0),
    path(0)
{
    /* Setup default brush for background */
    scDetail->bgBrush.setStyle(Qt::SolidPattern);
    scDetail->bgBrush.setColor(Qt::white);
    setBackgroundBrush(scDetail->bgBrush);

}
4

8 回答 8

26
  • 它更有效(通常)。一个类的所有成员都在构造函数中初始化,无论你是否显式初始化它们。如果不指定初始化程序,则运行成员的默认构造函数。如果您在构造函数主体中赋值,则再次调用赋值运算符。这不适用于标量值,如您的示例所示,因为标量值没有构造函数。
  • 您不能在初始化列表中意外地分配一个值两次。
  • 编译器可以检查以确保您编写初始化程序的顺序与在类中定义成员的顺序相匹配。C++ 标准要求成员按照声明的顺序进行初始化,而不管您编写初始化程序的顺序如何。让编译器检查这个顺序可确保程序员知道初始化程序将以哪个顺序运行(同样,这对于非 POD 成员比对标量更重要)。
  • 引用类型和const成员必须在初始化器列表中初始化,因为您不能分配给引用或const成员。
于 2008-10-02T10:34:12.137 回答
4

最好对初始化列表中的成员进行初始化,因为成员只会被初始化一次。如果成员本身就是类,这可能会在性能(甚至行为)上产生巨大差异。如果成员都是非常量、非引用的基本数据类型,那么差异通常可以忽略不计。

注意:有时基本数据类型需要初始化列表——特别是当类型是常量或引用时。对于这些类型,数据只能初始化一次,因此不能在构造函数的主体中初始化。有关更多信息,请参阅本文

请注意,成员的初始化顺序是成员在类定义中声明的顺序,而不是成员在初始化列表中声明的顺序。如果可以通过更改初始化列表的顺序来修复警告,那么我强烈建议您这样做。

我的建议是:

  • 你学会了喜欢初始化列表。
  • 您的同事了解成员初始化顺序的规则(并避免警告)。
于 2008-10-02T10:42:34.237 回答
3

除了 Greg Hewgill 的出色回答之外- 必须在初始化列表中设置 const 变量。

于 2008-10-02T10:48:41.120 回答
2

因为,在构造函数的主体中(“在大括号内”),成员变量已经是默认构造的。这可能会对性能产生一些影响,当您有一个具有非平凡构造的类型的成员变量时,当您首先将其默认构造,然后在构造函数中为其分配一些其他值时,当您可以自定义构造时它直接。

此外,某些类型可能不是默认构造的(例如引用),必须在初始化列表中构造。

于 2008-10-02T10:37:02.317 回答
2

如果你有 const 变量,它们的值不能通过赋值来设置。

将值分配给对象(不是内置函数或内在函数)时,初始化也更有效,因为不会像分配那样创建临时对象。

有关详细信息,请参阅C++ FAQ-Lite

于 2008-10-02T10:41:45.113 回答
0

看看在http://web.tiscali.it/fanelia/cpp-faq-en/ctors.html#faq-10.6收集的智慧

于 2008-10-02T10:40:49.437 回答
0

Greg 回答的另一个补充:必须在初始化列表中初始化没有默认构造函数的类型的成员。

于 2008-10-02T16:14:32.647 回答
0

Greg Hegwell 的回答包含一些很好的建议,但它没有解释编译器生成警告的原因。

当编译器处理构造函数的初始化列表时,项目按照它们在类声明中声明的顺序进行初始化,而不是按照它们在初始化列表中出现的顺序。

如果初始化列表中的顺序与声明顺序不同,一些编译器会生成警告(因此当项目未按列表顺序初始化时,您不会感到惊讶)。您没有包含您的类声明,但这可能是您看到警告的原因。

这种行为的基本原理是类的成员应该始终以相同的顺序初始化:即使该类有多个构造函数(这可能使成员在其初始化列表中的顺序不同)。

于 2010-05-06T16:39:59.160 回答