【问题标题】:class initialization list类初始化列表
【发布时间】:2011-01-07 11:54:25
【问题描述】:

只是一个关于 c++ 编码风格的简单问题,

例如,如果我们不做任何其他事情,将使用初始化列表中的默认构造函数调用一个类的所有成员变量。 B默认构造函数会被调用,值会被设置为0,int();

class A
{
   A();
private:
   B b;
   int value;
}

但是我的问题是,即使调用默认构造函数也是一个好习惯,总是自己做还是只在代码中添加额外的行

A::A() : b(), value() {}

【问题讨论】:

  • 输入 A::A() { } 是否总是一个好主意,即使它是空的?
  • 好吧,如果你不写:b(), value(),编译会为你做,所以它是不必要的,只有当你有一个参数来给构造函数时才使用初始化列表或者什么时候例如,您想将 int 设置为不为零的值
  • 不,没有它,POD 类型(例如value)将不会被初始化。

标签: c++ initialization


【解决方案1】:

你正在触及 C++ 的一个棘手的角落。

对象中 POD 值的初始化是粘性的,并且取决于一些事情。
即使我不确定我是否能正确理解所有规则,但我相信@Steve Jessop 曾经在 SO 上写过一篇关于这里的文章(尽管我目前可以找到它)。

但是一些例子:

此类将始终被初始化 b == false 并且 value = 0。

class A
{
   A() : b(), value() {}
   B b;
   int value;
};

如果没有 explicit 默认构造函数,它会更复杂:
在这里,编译器将为您生成一个默认构造函数。但是编译器生成的默认构造函数的工作方式取决于具体情况。 编译器生成的默认构造函数可以进行两种不同形式的初始化,具体使用哪种取决于上下文:

  1. 零初始化(所有 POD 成员都归零)
  2. 值初始化(所有 POD 成员都未定义)

例子:

class B
{
   B b;
   int value;
};

// Variables of static storage duration (notably globals)
// Will be zero initialized and thus b == false and value = 0

B   global; // Initialized

int main()
{
    // Object of automatic storage duration or dynamic storage duration
    // These will depend on how they are declared.

    // Value Initialization (POD re-mains undefined)
    B    bo1;           // b/value undefined
    B*   bp1 = new B;   // b.balue undefined

    // Zero Initialization
    B    bo2 = B();     // b = false, value = 0
    B*   bp2 = new B(); // b = false, value = 0

    // Note: The most obvious syntax for zero initializing a local object
    //        does not work as it is actually interpreted as a forward
    //        declaration of a function;
    B   bo3(); 
}

【讨论】:

    【解决方案2】:

    最好不要使用默认构造函数。编译器生成的构造函数比编写您自己的版本更可靠和可维护,除此之外,编写编译器可以为您编写的代码完全是浪费时间。如果你不需要任何构造逻辑,那就不要写构造函数。

    但是,除非您这样做,否则 int 不会被初始化,这是必须编写构造函数的糟糕理由。

    【讨论】:

    • (+1) 确认。更改类中属性的顺序也会导致重构列表——表示初始化顺序。
    • 在大多数情况下我同意。但是,如果该类包含 POD 成员,那么我将添加一个显式构造函数以确保对象在构造后处于定义的状态。除非该类实际上只是一个对象包(如上所示),在这种情况下,我会将其设为一个结构来反映这一事实。
    • @Raphael B.:大多数编译器都会警告您这一点(并且因为我总是将警告视为错误进行编译),从而防止您错过更改。
    【解决方案3】:

    默认情况下,int 变量不使用值初始化 - 你必须自己做。

    因此,当您不将成员变量“value”设置为构造函数中的某个值时,它会保持未初始化状态。

    【讨论】:

      【解决方案4】:

      只会为具有默认构造函数的类类型调用默认构造函数,而不会为基元调用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-13
        • 2015-05-22
        • 1970-01-01
        • 2021-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多