假设我们有一个具体的class Apple
。 (Apple 对象可以被实例化。)
现在,有人来导出一个摘要class Peach
来自苹果。它是抽象的,因为它引入了新的纯虚函数。 Peach 的用户现在被迫从它派生并定义这个新函数。这是常见的模式吗?这样做正确吗?
Sample:
class Apple
{
public:
virtual void MakePie();
// more stuff here
};
桃类:公共苹果
{
民众:
虚拟无效 MakeDeliciousDesserts() = 0;
// 这里还有更多内容
};
Apple 的 Re Peach:
- 如果苹果是一个价值阶层就不要这样做
(即有复制者,不相同
实例可以相等,等等)。见迈耶斯
更有效的 C++ 第 33 条了解原因。
- 如果苹果有公众就不要这样做
非虚拟析构函数,否则你
当你的
用户通过删除苹果
指向桃子的指针。
- 否则,你可能是安全的,因为你没有违反里氏可替代性 http://www.objectmentor.com/resources/articles/lsp.pdf。桃子就是苹果。
- 如果您拥有 Apple 代码,则更愿意分解出一个公共抽象基类(可能是 Fruit)并从中派生 Apple 和 Peach。
浆果番茄:
- 与上面相同,加上:
- 避免,因为它不寻常
- 如果必须,请记录 Tomato 的派生类必须执行哪些操作才能不违反里氏可替换性。您在 Berry 中重写的函数 - 我们称之为
Juice()
- 提出某些要求并做出某些承诺。派生类的实现Juice()
不能要求更多,承诺也不少。那么派生番茄就是浆果,并且只知道浆果的代码是安全的。
可能,您将通过记录衍生番茄必须调用来满足最后一个要求Berry::Juice()
。如果是这样,请考虑使用模板方法:
class Tomato : public Berry
{
public:
void Juice()
{
PrepareJuice();
Berry::Juice();
}
virtual void PrepareJuice() = 0;
};
现在,番茄很有可能是浆果,这与植物学的预期相反。 (例外情况是如果派生类的实现PrepareJuice
强加额外的先决条件Berry::Juice
).
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)