c++ - 非抽象但无状态的类对于多重继承是否与纯抽象类一样安全?
问题描述
在大多数书籍和文章中,进行多重继承的唯一“安全”(或至少是唯一建议的)方法是使用纯抽象基类(您可以称为虚拟接口)的虚拟继承。
原因主要是为了避免钻石问题,在这种问题中,数据成员的价值或非纯虚函数的实现状态可能会产生歧义。
纯抽象基类不会同时受到两者的影响(没有数据成员,没有非纯虚拟),虚拟继承甚至解决了基类实际内存地址的歧义。
但是给出这样的解释:如果歧义仅来自“状态”的形式(例如数据成员,静态函数变量),那么无状态的非抽象(甚至可能使用所有“最终”方法)类不是同样安全的是多重继承层次结构中的基类?
我错过了什么可能的问题?
PS:如果答案是“如果没有虚拟方法,那么无论如何你都可以使用组合”:除了学术兴趣之外,我有一个案例,我需要成员函数的属性才能能够无阴影,全局 C-样式函数,因此我无法通过指向组合对象的指针访问它们。
解决方案
虚拟继承通过避免非静态成员的重复副本已经实现了所需的安全性。变量和函数在这方面是一样的:即使基类是无状态的,如果它不止一次是基类,它的非静态成员函数也是模棱两可的。
虚拟继承还可以智能地处理覆盖:
struct B {
virtual ~B()=default;
virtual void f()/*=0*/;
};
struct X : virtual B {};
struct Y : virtual B {
void f() override;
};
struct D : X,Y {};
B& b();
void g() {
b().f(); // calls Y::f
}
是否B::f
是纯虚拟的并不重要。
所以无国籍不是重要的部分。此外,如果基础是无状态的,拥有final
成员将阻止默认存根实现的最明显用例。(唯一的this
另一种可能性是取决于好主意)。
所以你是正确的,非纯虚拟函数可以是安全的,但即使基础是有状态的也是如此。当然,多重继承的安全性仍然存在限制,例如重载集接受多个直接基时的歧义。
推荐阅读
- java - 如何在方法中使用 if...else 语句?
- tensorflow - 使用稀疏输入服务于 Tensorflow 模型
- javascript - 基于布尔状态 Reactjs 动态更改输入类型
- java - Java 扫描器无限地接受输入
- python - TF-Agents 自定义环境应急行动
- apache-kafka-connect - kafka-connect sink 连接器 pk.mode 用于具有自动增量的表
- javascript - React Native Firebase 拉取和推送数据问题
- microsoft-graph-api - 我可以使用 Microsoft Bot Framework 实现 Maker/Checker 机器人吗?
- google-chrome - Google Chrome 版本 91 导致带有 Struts 的旧版 JSP 丢失数据和格式
- r - 对矩阵列名进行排序以匹配列表中的元素顺序