gpt4 book ai didi

c++ - 从具体类派生抽象类

转载 作者:IT老高 更新时间:2023-10-28 21:45:48 27 4
gpt4 key购买 nike

假设我们有一个具体的 class Apple . (Apple 对象可以被实例化。)现在,有人来了,并得出了一个摘要 class Peach来自苹果。它是抽象的,因为它引入了一个新的纯虚函数。 Peach 的用户现在被迫从中派生并定义这个新功能。这是一种常见的模式吗?这样做正确吗?

示例:


class Apple
{
public:
virtual void MakePie();
// more stuff here
};<p></p>

class Peach : public Apple
{
public:
virtual void MakeDeliciousDesserts() = 0;
// more stuff here
};

现在假设我们有一个具体的 class Berry .有人推导出一个摘要 class Tomato从贝瑞。它是抽象的,因为它覆盖了 Berry 的一个虚函数,并使其成为纯虚函数。 Tomato 的用户必须重新实现之前在 Berry 中定义的功能。这是一种常见的模式吗?这样做是否正确?

示例:


class Berry
{
public:
virtual void EatYummyPie();
// more stuff here
};<p></p>

class Tomato : public Berry
{
public:
virtual void EatYummyPie() = 0;
// more stuff here
};

注意:名称是人为的,不反射(reflect)任何实际代码(希望如此)。写这个问题的过程中没有损害任何果实。

最佳答案

来自 Apple 的 Re Peach:

  • 如果 Apple 是值(value)类,请不要这样做(即具有复制ctor,不相同实例可以相等,等等)。见迈耶斯更有效的 C++ 条款 33 说明原因。
  • 如果 Apple 有公众号,请不要这样做非虚拟析构函数,否则你邀请未定义的行为,当你用户通过指向桃子的指针。
  • 否则,你可能是安全的,因为你没有违反 Liskov substitutability .桃子就是苹果。
  • 如果您拥有 Apple 代码,则更愿意分解出一个通用抽象基类(也许是 Fruit)并从中派生 Apple 和 Peach。

来自贝瑞的番茄:

  • 同上,另外:
  • 避免,因为它不寻常
  • 如果必须,请记录 Tomato 的派生类必须做什么,以免违反 Liskov 可替换性。您在 Berry 中重写的函数 - 我们称之为 Juice() - 提出了某些要求并做出了某些 promise 。 Juice() 的派生类的实现不能要求更多,也不能要求更少。那么 DerivedTomato IS-A Berry 和只知道 Berry 的代码是安全的。

您可能会通过记录 DerivedTomatoes 必须调用 Berry::Juice() 来满足最后一个要求。如果是这样,请考虑改用模板方法:

class Tomato : public Berry
{
public:
void Juice()
{
PrepareJuice();
Berry::Juice();
}
virtual void PrepareJuice() = 0;
};

现在很有可能番茄是浆果,这与植物学的预期相反。 (异常(exception)情况是,如果派生类的 PrepareJuice 实现强加了超出 Berry::Juice 强加的额外前提条件。

关于c++ - 从具体类派生抽象类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/310408/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com