如果未继承,为什么要调用构造函数
why constructors are called if they are not inherited?
代码正在打印所有构造函数。我读到,当我们从另一个类得出类时,构造函数并未继承。那么为什么创建c
是从b
和a
class A
{
public:
A() { cout << "A's constructor called" << endl; }
};
class B
{
public:
B() { cout << "B's constructor called" << endl; }
};
class C: public B, public A // Note the order
{
public:
C() { cout << "C's constructor called" << endl; }
};
int main()
{
C c;
return 0;
}
当您读取的文档所述构造函数是"未继承"时,这意味着如果类A
定义了构造函数A::A(int x)
,则儿童类B
将不会自动有一个采用int
的构造函数。
但是,仍然有必要初始化父类的值。否则,父对象可能处于无效状态。构造函数用于初始化类,因此,含义是父级构造函数的必须从子构建体的 initializer list 中调用。如果父类具有默认构造函数,则默认情况下会调用。这就是您在示例中看到的。如果父母不提供默认构造函数,则必须指定要称为哪个:
class A
{
public:
A(int x) { cout << "A's constructor called" << endl; }
};
class C: public A
{
public:
C()
: A(7) /* compilation will fail without this line */
{ cout << "C's constructor called" << endl; }
};
构造函数不是传统意义上的。
类是继承的。
,但是要构建一个类,需要调用其构造函数。那是它的工作。硬规则,没有例外。
当您从第二类继承一个类时,构建第一类也需要构建第二类。因为第一类总是包含第二类。另一个艰难的规则,没有例外。这就是"继承"的含义。
因此,构建头等舱将调用其构造函数。然后,要构建第二类,也需要调用其构造函数(实际上第二类首先构造,然后进行第一类的构造)。
这就是为什么两个构造函数都将被使用。
我读到当我们从其他类得出类时,构造函数不是继承的
那是正确的。但是,您似乎误解了这一点的含义。
假设您有:
struct A
{
A(int) {}
};
struct B : A
{
B() : A(0) {}
};
给定上述,您将无法使用:
B b(10);
因为A(int)
未继承B
。
那是您误会的关键。
那么,为什么C的创建是从B和A
调用构造函数的
但是,当您构造B
时,B
的构造函数被调用以初始化其成员。还必须调用A
的构造函数,以便可以初始化与A
相对应的B
的子对象。
有几种方法可以初始化A
的B
。
您可以使用语法:
在成员初始化列表中明确使用A
的构造函数:B() : A(0) {}
将成员初始化留为空,在这种情况下,
A
的默认构造函数称为B() {}
等效于:
B() : A() {}
在我介绍的示例中,这将导致编译器错误,因为通过提供与默认构造函数不同的另一个构造函数删除了
A
的默认构造函数。
回到您对C
默认构造函数的实现,您有:
C() { cout << "C's constructor called" << endl; }
等效于
C() : B(), A() { cout << "C's constructor called" << endl; }
B::B()
和 A::A()
在构造C
的实例时调用。
构造函数在classens 上 在继承时。继承基本上给出了基本类的派生类实例匿名成员实例,以及其他事项。这些实例需要构造以使其构造函数称为。
"构造函数不是继承的"意味着,C类应该并且将拥有自己的构造函数,尽管有B的构造函数,但它将无法使用B的构造函数而不是C的构造函数。这正是您得到的:您将获得所有父级的构造函数。
当您拥有课堂的层次结构并从一个构建对象时,他的所有父母将从基础上开始。
。当您将它们摧毁时,将从他开始,他和他所有的父母会造成顺序破坏。
按规则:首次创建 - 最后破坏。
否未继承,C 11标准表示此
class A
{
public:
A(int x) {}
};
class B: public A
{
};
int main(void)
{
B b(5);
return 0;
}
这将无法编译,因为A(int)
没有继承。您可以将B
定义为
A(int)
class B: public A
{
using A::A;
};
在您的情况下,您正在定义所有默认ctors,并且是否明确定义,仍然存在,并且由于您的C c
声明而将其称为对象初始化的一部分。
c 继承基本上创建了由其超级类别的部分组成的类。例如:
class A {
public:
A() {
std::cout << "Constructor A" << 'n';
}
};
class B : public A {
public:
B() {
std::cout << "Constructor B" << 'n';
}
};
class C : public B {
public:
C() {
std::cout << "Constructor C" << 'n';
}
};
C类实际上是C类,带有B类部分和A类A零件。因此,为了构建C类,我们需要通过调用这些部分的构造函数来构造其每个部分。这些构造函数的顺序是从最基本的类到最衍生的类(在这种情况下为a至c)。最大的是继承树顶部的班级,最衍生的是底部的班级。
同样的规则也适用于破坏者。唯一的区别是,从大多数衍生到大多数基础(c至a)的驱动器被调用。
- 在c++中使用向量时,如何调用构造函数和析构函数
- C++:考虑但不调用构造函数的特殊性
- 对象实例化调用构造函数的次数太多
- 我使用向量来创建类对象列表.初始化向量时如何使用参数调用构造函数?
- C ++:通过大括号调用构造函数?
- 不能调用构造函数
- 赋值 boost::intrusive_ptr 而不调用构造函数?
- 在模板化类的构造函数中调用构造函数
- 如何为 std::vector 分配内存,然后稍后为某些元素调用构造函数?
- 为什么从另一个构造函数内部调用C++构造函数不修改类变量?
- 静态 std::map instatiation 在类的方法中调用构造函数吗?
- 有没有一种简单的方法可以在对象向量上调用构造函数?
- 我不明白在这个例子中什么时候调用构造函数
- 调用c++构造函数的不同方法
- 调用构造函数与将内联常量定义为默认参数
- 如何通过 Rust FFI 调用C++构造函数?
- "new"运算符是否总是调用构造函数?
- 无法调用构造函数
- 使用 "()" 调用构造函数不同于"{}"
- 确定是调用构造函数还是强制转换运算符的因素