这是多重继承的良好用法吗?
Is this a good use of multiple inheritance?
我发现了一些代码,其中基类的派生被用作一种标志,将某些对象标记为属于特定组:
// Base type for any item to be stored in a Storage.
class Item { // trivial class (as shown here)
public:
virtual ~Item() {}
};
class BaseItem; // complex class
class ItemA : public BaseItem, public Item; // complex class
class Storage;
由于已经有一个基类可以从中派生,因此我们得到了多重继承。
考虑到多重继承的性能成本以及此代码必须高效的事实,这是否是一种好方法?
一个简单的标志会是更好的选择吗?
主要问题是:">ItemA
的行为与BaseItem
和Item
的行为有何不同?事实上,你甚至可以问:"BaseItem
的行为与Item
有什么不同?继承主要用于您希望继承类型之间的常见行为,但这些类型之间的行为存在一些差异(参见"为什么要使用继承?如果这些项目在行为上完全没有区别,那么有更简洁的方式来表示每个项目的一些特殊"类型",而不必定义实际的......为他们键入,例如,使用您已经提议的标志。如有疑问,请保持简单。
在性能方面...好吧,在这个阶段甚至根本不考虑性能:是的,使用虚拟成员对运行时的影响非常小,但对于几乎所有目的来说,这都是无关紧要的。然而,通过多重继承,很容易迅速制造出没有人愿意试图理解的脑痛混乱。尽管如此,使用MI还是有一些很好的理由,但要非常非常小心。
这完全没问题。这就是C++的做法。例如,basic_istream
和 basic_ostream
都继承自基类basic_ios
。然后basic_iostream
继承了basic_istream
和basic_ostream
。看起来像这样:
https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-3.4/classstd_1_1basic__iostream__inherit__graph.png
一个简单的标志可能是更好的选择,但它取决于。我已经看到这种类型的琐碎基类用于允许编译时检查对象是否被允许做某事。
执行此操作或使用标志的运行速度是否更快取决于您如何使用它。在我给出的示例中,代码随后使用 dynamic_cast
s 从基指针获取派生指针。这会产生运行时成本,这可能使标志更有效率,但程序员希望编译时检查以防止其他程序员尝试错误地使用系统,因此他做出了权衡。
虚拟表确实有性能开销,但开销不大(我执行的测试使我相信性能仅比 switch 语句慢一点(,所以我不会担心这一点,除非您正在编写嵌入式系统或编写每秒将执行数百万次或更多的函数。
- 关于C++中具有多重继承"this"指针的说明
- C++中模板化异常类的多重继承
- 虚拟继承中是否存在多重继承?
- 如何在 c++ 多重继承中调用父非虚函数?
- 多重继承相同的方法名,没有歧义
- 使用enable_if解决多重继承歧义
- 多重继承导致虚假的模糊虚拟函数过载
- 多重继承和访问不明确的元素
- C++ 多重继承:使用基类 A 的实现实现基类 B 的抽象方法
- 多重继承中的派生类的行为类似于聚合
- 为什么我的 Hippomock 期望在使用多重继承时失败
- 带有此指针的模板类多重继承构造函数不起作用?
- 使用多重继承时出现编译错误
- 增强多重继承的序列化
- 多重继承:跳过'virtual'关键字并拒绝菱形层次结构的使用?
- 仅函数的多重继承 - 没有虚拟和 CRTP
- C++多重继承和鸭子类型
- C++两次从文件保存对象读取多重继承
- 从多重继承中的派生类函数调用适当的父类函数
- 这是多重继承的良好用法吗?