【问题标题】:Should I call the base class default constructor in the initialization list?我应该在初始化列表中调用基类默认构造函数吗?
【发布时间】:2011-04-25 15:42:07
【问题描述】:
class A : public B
{
  ...
}

// case I : explicitly call the base class default constructor
A::A() : B()
{
  ...
}

// case II : don't call the base class default constructor
A::A() // : B()
{
  ...
}

案例二等于案例一吗?

对我来说,我假设在情况 II 中不会调用基类 B 的默认构造函数。然而,尽管仍然持有这个假设,但我已经运行了一个测试,证明并非如此:

class B
{
public:
    B()
    {
        cout << "B constructor" << endl;
    }
};

class A : public B
{
public:
    A()
    {
        cout << "A constructor" << endl;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    A a;
    return 0;
}

//VS2008的输出

B constructor
A constructor
Press any key to continue . . .

【问题讨论】:

    标签: c++ inheritance constructor


    【解决方案1】:

    在这两种情况下都会调用基类构造函数。

    这里是 link 以获取更多信息。

    【讨论】:

      【解决方案2】:

      如果基类构造函数不带任何参数,则不需要在初始化列表中明确提及。

      【讨论】:

        【解决方案3】:

        如果B 没有用户声明的构造函数,则行为不同。比较:

        struct SimpleAggregate {
          int a;
          float b;
        };
        
        struct ClassWrapper : SimpleAggregate {
          ClassWrapper() : SimpleAggregate() { }
        };
        
        ClassWrapper w;
        

        现在,w.aw.b 保证为零。如果您放弃基类的显式初始化,它们将具有不确定的值。


        您可能不知道,尽管有语法,但上面对SimpleAggregate() 的使用确实调用了默认构造函数。它只是对基类进行值初始化(我们在 Stackoverflow 上有几个关于“值初始化”是什么的好答案),而不是调用默认构造函数,因为没有用户声明。

        【讨论】:

        • 这是一个的区别。这个应该被接受为答案。
        【解决方案4】:

        为了完成学习体验并加深理解,您可以开始稍微修改一下。例如,当B 没有默认构造函数时会发生什么?它甚至可以编译吗?像这样的其他轻微修改将提供很好的学习体验。

        也就是说,根据我的经验,这样做通常会更好

        A::A() : B() { ... } 
        

        A::A() { ... } 
        

        因为前者更明确,它会让你思考基类初始化的真正情况。您可能会通过明确说明事情来避免隐藏行为。

        【讨论】:

        • 我给了你一个加分,因为你提出了提高人们对这个主题的理解的方法。
        • 我给 +1 是因为这回答了“应该……”的问题。大多数其他答案都是针对相关问题“必须...”。
        【解决方案5】:

        从其他类派生的每个类都必须调用基类的构造函数。只有在所有基类都完全构造后,才能构造派生类。因此,是否调用基类的构造函数并不重要。如果不调用,只要有默认构造函数可供编译器判断,就会被调用。否则编译器会报错。

        【讨论】:

          猜你喜欢
          • 2015-07-10
          • 1970-01-01
          • 2011-07-01
          • 1970-01-01
          • 1970-01-01
          • 2016-06-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多