我找到了一些代码,其中从基类派生用作一种标志,将某些对象标记为属于特定组:
// 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;
由于已经有一个派生的基类,我们得到了多重继承。
考虑到多重继承性能方面的成本以及此代码必须高效的事实,这是一个好的方法吗?
简单的旗帜可能是更好的选择吗?
答案 0 :(得分:3)
主要问题是:" ItemA
的行为与BaseItem
和Item
的行为有何不同?" 事实上,您甚至可以问:" BaseItem
的行为与Item
的行为有何不同?"当你想要继承类型之间的共同行为时,主要使用继承,但是它们之间的行为存在某些差异(参见"Why use inheritance at all?")。如果这些项目的行为完全不同,那么可以更清晰地表达一些特殊的" type"每个项目,而不必为他们定义实际的... type,例如你已经提出了一面旗帜。如有疑问,keep it simple。
在表现方面......嗯,在这个阶段甚至不考虑的表现:是的,there will be a very small runtime impact of using virtual members,但几乎所有目的都是无关。然而,通过多重遗传,很容易快速制造引起大脑痛苦的混乱,这是任何人都不想尝试理解的。不过,there are some good reasons for using MI, but be very, very careful with it。
答案 1 :(得分:2)
当然这很好。这就是C ++如何做到的。例如,basic_istream
和basic_ostream
都从基类basic_ios
继承。然后basic_iostream
继承basic_istream
和basic_ostream
。看起来像这样:
答案 2 :(得分:2)
一个简单的标志可能是一个更好的选择,但它取决于。我已经看到过这种简单的基类,用于允许编译时检查对象是否允许执行某些操作。
执行此操作或使用标志是否运行得更快取决于您如何使用它。在我给出的示例中,代码然后使用dynamic_cast
来从基指针返回派生指针。这有一个运行时成本,这可能使标志更有效,但程序员希望编译时检查,以防止其他程序员尝试错误地使用系统,所以他做了一个权衡。
虚拟表确实有性能开销,但不是很多(我执行的测试让我相信性能只比switch语句慢一点),所以我不担心这个除非您正在编程嵌入式系统或编写将每秒执行数百万次或更多次的函数。