创建从虚类继承的类
creation of a class that inherits from a virtual class
我想我理解了虚拟类的核心原理。但是我真的很困惑,当创建从虚类继承的对象时,到底发生了什么。
例如:(输出为5)
#include <iostream>
using namespace std;
struct A {
public: int myInt;
A():myInt(5) {}
A(int n): myInt(n) {}
};
class B : virtual public A {
public:
B(int n):A(10) {} B():A(10) {}
};
class C : virtual public A {
public:
C(int n):A(3*n) {}
};
class D : public B, public C {
public:
D(int n=90) : C(2*n), B(n) {}
};
int main() {
D d(100);
cout << d.myInt << endl;
return 0;
}
我明白,首先,最派生的类必须构造虚类。然后,基类,然后进入构造函数。
但是当用"创建的A的单个实例"来构造C和B的"A部分"时会发生什么呢?我知道,首先,A的构造函数被隐式调用,因为有一个默认构造函数),然后是所有直接的基类。
我猜,当创建,例如,C的A部分,A的构造函数不会被再次调用,因为它已经创建。我说的对吗?
但是当用"创建的A的单个实例"来构造C和B的"A部分"时会发生什么呢?我知道,首先,A的构造函数被隐式调用,因为有一个默认构造函数),然后是所有直接的基类。
这取决于B
或C
是由自身构成还是作为D
的子对象。当它们被构造为D
对象的子对象时,你所说的是正确的。这是真的,因为D
的构造函数在初始化列表中没有显式调用A
的任何构造函数。
既然你使用了:
B(int n):A(10) {} B():A(10) {}
当您使用
构造B
时B b;
A()
没有被使用,但是A(10)
被用来构造A
子对象。
我猜,例如,当创建
C
的A
部分时,A
的构造函数不会被再次调用,因为它已经创建了。我说的对吗?
您可以查看isocpp.org,特别是:"再一次:在多重继承和/或虚拟继承情况下,构造函数的确切顺序是什么?",其中声明:
首先要执行的构造函数是层次结构中任意位置的虚基类。它们按照它们在基类图的深度优先的从左到右遍历中出现的顺序执行,其中从左到右指的是基类名出现的顺序。
所有虚基类构造函数完成后,构造顺序一般是从基类到派生类。如果您想象编译器在派生类的actor中做的第一件事是对其非虚拟基类的actor进行隐藏调用,那么细节就很容易理解了(提示:许多编译器实际上就是这样做的)。因此,如果类D从B1和B2继承了乘法,则B1的构造函数先执行,然后是B2的构造函数,然后是D的构造函数。例如,如果B1继承了B1a和B1b, B2继承了B2a和B2b,那么最终的顺序是B1a、B1b、B1、B2a、B2b、B2、d。
请注意,B1和B2(或B1a和B1b)的顺序是由基类在类声明中出现的顺序决定的,而不是由初始化器在派生类的初始化列表中出现的顺序决定的。
- 如何创建从同一类继承的不同对象的向量
- 如果'C'公开继承'B',B 私下继承'A',为什么我不能在"C"中创建"A"的对象?
- 如何创建没有特定定义的随机分布?uniform_int_distribution是从其他类继承的吗?
- 从抽象类继承以创建另一个抽象类时,我应该重新声明所有虚函数吗?
- 了解虚拟继承类 vtables 和 vptr 创建
- 如何从继承的父类创建unique_ptr
- 创建一个具有两个可能继承的类
- 如何创建一个继承自 std::vector 的类
- 是否有可能有一个派生类继承最终函数但创建相同的函数(而不是重写)
- 创建一系列超类的指针,以分配继承的类
- 如何创建从版本继承的CMAKE配置类型
- 动态创建一个继承的类,使用STD :: MAP使用基类指针访问
- 创建一个函数,该函数返回具有现有类继承的不同类型
- 如何允许一个类由另一个类创建而不使用'friend'但允许继承?
- 如何创建一个新类来继承 ostream 并将其用作 cout 但带有锁定
- 无法创建两个从 std::logic_error 继承的自定义异常类
- 如何在Qt Creator中从继承的类自动创建虚拟方法
- 在构造函数 QT 创建器(继承类)中传递默认参数
- 如果对象是堆栈创建的(包括继承的类型),是否可以发出编译错误
- C++使用模板和继承创建函数映射