C++ C++;包含类变量初始化的类初始化

C++ C++;包含类变量初始化的类初始化,c++,class,coding-style,C++,Class,Coding Style,我注意到今天一位同事的一些代码在初始化中初始化了类变量。然而,他说,这是因为他们的秩序,所以引起了警告。我的问题是,为什么在当前位置进行变量初始化更好,而不是在花括号内 DiagramScene::DiagramScene( int slideNo, QRectF screenRect, MainWindow* parent ) : QGraphicsScene( screenRect, parent ), myParent( parent ), slideUndoIm

我注意到今天一位同事的一些代码在初始化中初始化了类变量。然而,他说,这是因为他们的秩序,所以引起了警告。我的问题是,为什么在当前位置进行变量初始化更好,而不是在花括号内

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

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

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


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

请查看收集的智慧,如果您有常量变量,则无法通过赋值设置它们的值

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


有关更多详细信息,请参见

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

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

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

我建议:

  • 您将学会喜欢初始化列表
  • 您的同事了解成员初始化顺序的规则(并避免警告)

除了Greg Hewgill的-常量变量必须在初始化列表中设置。

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

Greg Hegwell的答案包含一些非常好的建议,但它并没有解释编译器为什么会生成警告

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

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


这种行为的基本原理是,类的成员应始终以相同的顺序初始化:即使类有多个构造函数(可能会使成员在其初始值设定项列表中的顺序不同)讽刺的是,这看起来就像是C++ FAQ Lite的一个副本。只是一个通用术语注释:这是关于成员变量的。成员变量属于一个对象。类变量在C++中不存在,而它们在Ruby中也存在,并且或多或少地服务C++静态成员变量的目的。