在这种特定情况下,使用成员初始化列表和在构造函数中分配值之间是否存在差异?

Ste*_*tef 88 c++ initialization initialization-list

在内部和关于生成的代码,是否有真正的区别:

MyClass::MyClass(): _capacity(15), _data(NULL), _len(0)
{
}
Run Code Online (Sandbox Code Playgroud)

MyClass::MyClass()
{
  _capacity=15;
  _data=NULL;
  _len=0
}
Run Code Online (Sandbox Code Playgroud)

谢谢...

ste*_*anB 77

您需要使用初始化列表来初始化常量成员,引用和基类

当您需要初始化常量成员,引用并将参数传递给基类构造函数时,如注释中所述,您需要使用初始化列表.

struct aa
{
    int i;
    const int ci;       // constant member

    aa() : i(0) {} // will fail, constant member not initialized
};

struct aa
{
    int i;
    const int ci;

    aa() : i(0) { ci = 3;} // will fail, ci is constant
};

struct aa
{
    int i;
    const int ci;

    aa() : i(0), ci(3) {} // works
};
Run Code Online (Sandbox Code Playgroud)

示例(非详尽)类/结构包含引用:

struct bb {};

struct aa
{
    bb& rb;
    aa(bb& b ) : rb(b) {}
};

// usage:

bb b;
aa a(b);
Run Code Online (Sandbox Code Playgroud)

以及初始化需要参数的基类的示例(例如,没有默认构造函数):

struct bb {};

struct dd
{
    char c;
    dd(char x) : c(x) {}
};

struct aa : dd
{
    bb& rb;
    aa(bb& b ) : dd('a'), rb(b) {}
};
Run Code Online (Sandbox Code Playgroud)

  • 如果`_capacity`,`_data`和`_len`有没有可访问的默认构造函数的类类型? (4认同)
  • 您可以调用构造函数可用的内容,如果需要设置更多值,则可以从构造函数的主体中调用它们.这里的区别在于你不能初始化构造函数体中的`const`成员,你必须使用初始化列表 - 非`const`成员可以在初始化列表或构造函数体中初始化. (2认同)
  • 您还必须初始化初始化列表中的引用 (2认同)
  • @stefanB:道歉,如果我暗示你实际上并不明白这一点.在你的回答中你只说明了在初始化列表中必须命名一个基数或成员时,你还没有解释初始化初始化列表和构造函数体中的赋值之间的概念差异究竟是哪个是我误解的地方可能来自. (2认同)

tem*_*def 59

假设这些值是原始类型,那么不,没有区别.只有在将对象作为成员时,初始化列表才会有所不同,因为初始化列表不是使用默认初始化,而是使用赋值,而是允许您将对象初始化为其最终值.这实际上可以明显更快.

  • 就像Richard说的那样,如果这些值是原始类型和const,那么初始化列表是将值赋给const成员的唯一方法. (17认同)
  • 它只能在变量不是引用或常量时描述,如果它们是常量或引用,它甚至不使用初始化列表就可以编译. (11认同)

Ric*_*ook 18

是.在第一种情况下,您可以声明_capacity,_data_len作为常量:

class MyClass
{
private:
    const int _capacity;
    const void *_data;
    const int _len;
// ...
};
Run Code Online (Sandbox Code Playgroud)

如果要const在运行时计算它们的值时确保这些实例变量的性能,这将非常重要,例如:

MyClass::MyClass() :
    _capacity(someMethod()),
    _data(someOtherMethod()),
    _len(yetAnotherMethod())
{
}
Run Code Online (Sandbox Code Playgroud)

const必须在初始化程序列表中初始化实例,或者基础类型必须提供公共无参数构造函数(基元类型可以).

  • 参考资料也是如此.如果您的类具有引用成员,则必须*在初始化列表中初始化它们. (2认同)

use*_*404 6

我认为这个链接http://www.cplusplus.com/forum/articles/17820/提供了一个很好的解释 - 特别是对于那些刚接触C++的人.

intialiser列表更有效的原因是在构造函数体内,只进行赋值,而不是初始化.因此,如果您正在处理非内置类型,则在输入构造函数的主体之前已经调用了该对象的默认构造函数.在构造函数体内,您要为该对象赋值.

实际上,这是对默认构造函数的调用,然后是对复制赋值运算符的调用.初始化列表允许您直接调用复制构造函数,这有时会明显更快(回想一下初始化列表在构造函数的主体之前)


Fre*_*son 5

我将补充一点,如果你有类类型的成员没有可用的默认构造函数,初始化是构建类的唯一方法.