我刚刚开始学习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; }
};
继承的构造函数也可以来自类的父级 - 例如:
Child(args) : Parent(args) { ...extras }
在我更熟悉的语言中或多或少地像Child(args) { super(args); ...extras }
那样行事。如果我们还有复杂的属性(比如prop1是一个复杂的类 - 一个字符串或其他东西),那么我们可以通过它们的构造函数实例化它们:
Child(args) : Parent(args), prop1(args) { ...extras }
这是否适当地总结了一切?我是否缺少任何方面,或者对我所陈述的内容进行有用的阐述?
答案 0 :(得分:1)
您滥用继承一词。
这些是子对象构造函数,子对象包括成员变量和基类子对象。单词 inheritance 仅适用于基类子对象。成员子对象的相应单词是组合。
使用 ctor-initializer 列表比构造函数体内的赋值更好,原因有两个:
在为子对象构造函数构建参数列表时,您还可以使用函数和任意表达式 - 它们不必仅仅是传递给构造函数的参数。
如果使用一对空括号,您将获得子对象的值初始化,而不是默认初始化。如果有默认构造函数,则它们是相同的。否则,值初始化将使您的子对象归零,而默认初始化将留下不确定的,可能是非法的状态。
在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)} {}
};