为什么要使用虚拟基类
Why Should I use virtual base classes?
根据我所读到的,当你有一个保存数据的抽象基类时,就会使用虚拟基类,所以这个类不会被复制,但是,如果你不使用虚拟类,复制这个类有什么问题?
是否应该避免保存数据的抽象基类?
下面是一个示例:
class Storable {
public:
Storable(const string& s);
virtual void read() = 0;
virtual void write() = 0;
virtual ~Storable();
protected:
string file_name; // store in file named s
Storable(const Storable&) = delete;
Storable& operator=(const Storable&) = delete;
};
class Transmitter : public virtual Storable {
public:
void write() override;
// ...
};
class Receiver : public virtual Storable {
public:
void write() override;
// ...
};
class Radio : public Transmitter, public Receiver {
public:
void write() override;
// ...
};
这个例子取自《C++编程语言》一书。 第 4 版 - Bjarne Stroustrup。
简而言之,如果您不对Storable
使用虚拟继承,那么Radio
将继承它两次,一次来自Transmitter
,一次来自Receiver
。
这意味着Radio
需要内存来存储 2 个 Storable
实例,这是一些内存开销,并且您很可能希望两者都具有相同的数据(如果您实际上没有继承它,则必须手动管理它)。
此外,当您从Storable
调用基类函数(或访问数据成员)时,要调用哪一个?通过Transmitter
继承的Storable
或通过Receiver
继承的Storable
的
虚拟继承通过仅具有所有继承类共享的Storable
基类的单个实例来处理这个问题。
有关虚拟基类的 mor 信息,这里有一个很好的问题:C++,什么是虚拟基类?
虚拟基类用于虚拟继承,是一种在使用多个继承时防止给定类的多个"实例"出现在继承层次结构中的方法,即只是为了避免DIAMOND PROBLEM
。为了避免这个菱形问题,我们要么使用虚拟基类,要么使用"::",即范围解析运算符,以清楚地了解我们要使用的类的方法或数据。请参考钻石问题
相关文章:
- 子类地址等于虚拟基类地址?
- 虚拟基类函数中派生类的大小
- 虚拟基类初始化
- 虚拟基类在内部如何工作?编译器如何解析对基方法的调用?
- 返回纯虚拟基类的向量的元素
- std::is_base_of和虚拟基类
- 如何在子类中重写时调用私有虚拟基类实现
- 从两个不同类继承的非虚拟基类的访问成员
- 为什么必须由最派生的类构建虚拟基类
- 虚拟基类的派生类列表
- boost::bind 无法绑定到纯虚拟基类中定义的非静态函数模板成员类型
- 虚拟基类和继承
- (为什么)纯虚拟派生类中是否需要虚拟基类构造函数调用?
- 在派生类中使用虚拟基类的受保护的CTOR
- 私有非虚拟基类函数被称为派生类中的函数
- 虚拟基类的创建顺序
- 使用虚拟基类C++向下转换
- 为什么在派生最多的类的初始值设定项列表中显式调用虚拟基类构造函数的规则,而较老的祖先已经拥有它?
- 虚拟与纯虚拟基类函数并从DLL导出
- 在多级继承中派生的虚拟基类会发生什么