初始化非指针类成员

8
最近,我一直在阅读备受好评的C++ FAQ中关于构造函数的内容。其中一篇文章提到,最好使用初始化列表来初始化类成员,而不是在构造函数代码块内部初始化。
这是因为编译器往往会创建多个类成员副本,而不仅仅是一个副本。 示例 好的
Foo::Foo( void )
    : mBar( new Bar ) //pointer to some memory address
{
}

坏的

Foo::Foo( void )
{
    mBar = new Bar;
}

它还指出了一件事情(虽然这与构造函数有关,但也适用于从非成员函数中进行的对象纯初始化),即在通过以下方法初始化对象时:

void f( void )
{
    Foo foo( Bar() ); //Bad.

    foo.x(); //error
}

你需要声明一个非成员函数,该函数返回一个Foo对象。(点击上面的链接获取更多信息)
问题是,因为这个原因,是否拥有以下内容是不明智的:
Geometry::Geometry( void )
    : mFaces( QVector< GLushort >() ),
      mFinalized( false ),
      mNormals( QVector< QVector3D >() ),
      mVerticies( QVector< QVector3D >() )

甚至是这个:

Geometry::Geometry( void )
    : mFaces( QVector< GLushort > ),
      mFinalized( false ),
      mNormals( QVector< QVector3D > ),
      mVerticies( QVector< QVector3D > )

由于这些对象的分配方式(即它们不是指针),让我想知道这些对象是否需要在开始时初始化。如果需要,这是正确的方法吗?还是有更好的初始化方法?
与问题的关联
这与C++构造函数初始化背后的方法论相关,因为它涉及使用构造函数初始化对象的方式,以及我是否无知于堆栈上分配的对象 - 或者,我认为无论如何,没有指针分配的对象 - 是否需要在第一时间进行初始化。
1个回答

13

如果成员变量是由用户声明的默认构造函数的类类型,则您不需要在初始化列表中显式提及它:在构造期间,在进入构造函数主体之前,该变量的默认构造函数将被调用。

如果成员变量是原始类型(例如intbool)或者是没有任何用户声明的构造函数的类类型,则您需要显式初始化它,否则它将不会被初始化(并且它将具有未知值;您无法读取未初始化的对象)。


那么,根据上面的代码,这是否意味着我只是创建了多个分配的对象的副本? - zeboidlund
3
当您使用mFaces(QVector<GLushort>())时,您会构造一个临时的QVector<GLushort>对象,从该临时对象复制构造mFaces,然后销毁该临时对象。所以,是的,您正在创建比必要更多的对象。 - James McNellis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接