C ++:构造函数,继承和初始化

时间:2014-03-30 05:13:10

标签: c++ inheritance constructor initialization

我刚刚开始学习C ++,并且对实例化,构造函数声明和继承的相互作用感到有些困惑......我想我已经开始围绕一切,但我想制作我确定我已经正确地概念化了事情。我提供了一个班级以及我认为正在进行的事情的列表:

class Classy{
private:
    int foo1;
    int foo2;
public:
    //constructor 1
    Classy() { foo1 = 0; foo2 = 0; }
    //constructor 2
    Classy(int bar1) : foo1(bar1), foo2(0) {}
    //constructor 3
    Classy(int bar1, int bar2) : foo1(bar1) { foo2 = bar2; }
};
  • 构造函数1以我习惯的方式做事;对构造函数的调用通过赋值来设置foo属性。
  • 构造函数2使用来自int类的继承构造函数。
  • 构造函数3是上述的组合。

继承的构造函数也可以来自类的父级 - 例如:

Child(args) : Parent(args) { ...extras }

在我更熟悉的语言中或多或少地像Child(args) { super(args); ...extras }那样行事。如果我们还有复杂的属性(比如prop1是一个复杂的类 - 一个字符串或其他东西),那么我们可以通过它们的构造函数实例化它们:

Child(args) : Parent(args), prop1(args) { ...extras }

这是否适当地总结了一切?我是否缺少任何方面,或者对我所陈述的内容进行有用的阐述?

1 个答案:

答案 0 :(得分:1)

您滥用继承一词。

这些是子对象构造函数,子对象包括成员变量和基类子对象。单词 inheritance 仅适用于基类子对象。成员子对象的相应单词是组合

使用 ctor-initializer 列表比构造函数体内的赋值更好,原因有两个:

  • 它可用于没有默认构造函数的类型。
  • 它可用于无法分配的类型,例如引用和const成员变量。
  • 效率更高,因为它不需要首先使用默认构造函数创建状态,只需更换它。

在为子对象构造函数构建参数列表时,您还可以使用函数和任意表达式 - 它们不必仅仅是传递给构造函数的参数。

如果使用一对空括号,您将获得子对象的值初始化,而不是默认初始化。如果有默认构造函数,则它们是相同的。否则,值初始化将使您的子对象归零,而默认初始化将留下不确定的,可能是非法的状态。

在C ++ 11中,在调用子对象构造函数时,通常希望使用通用初始化程序语法{}而不是()

以下是这些语法有用的示例:

class Classy
{
  // private is the default access specifier for classes
    int bar[100];
    const std::array<int, 100> baz;
    static std::array<int, 100> make_array(int x)
    {
        std::array<int, 100> retval;
        for( int i = 0; i < 100; ++i )
            retval[i] = i * x;
        return retval;
    }
public:
    //constructor 1
    Classy() : bar{}, baz{} {}
    //constructor 2
    Classy(int bar1) : bar{}, baz{make_array(bar1)} {}
};