我对OOP和C ++语言都很陌生。 最近我被赋予了一个面向对象设计的任务 - 考虑到我对这个主题缺乏了解,我想到目前为止我已经做得很好。而且既然我想要像我迄今为止做得更好或更好,我想让我的疑问得到澄清。
我做了一个设计,其中基类提供了两个虚函数。有些孩子实现了父母的虚拟功能,但有些孩子只实现了一个。 现在,我知道这不是最好的/干净的设计,如果我没有实现(在某些孩子中)这些虚拟方法中的一个,我可能会收到编译器的警告。我知道我可以实现这些方法,当它们不需要时,它们可以简单地返回异常,或者什么也不做。
尽管如此,我的疑问/问题是:未在孩子中实施这些虚拟方法的实际风险是什么?在没有虚方法实现其父对象的对象上会发生什么?我正在寻找一个相当深刻的洞察力 - 我的意思是,我正在寻找对物体的胆量等级的理解。
如果无法给出解释,任何可能的参考资料都将受到欢迎和赞赏。
干杯!
修改 你好。谢谢大家的回答。我最初的问题 - 至少在我脑海中 - 与ViktorChvátal建议的“可能重复”无关 - 但是他指出这个问题,随着我问题的所有其他答案的澄清并消除了我的怀疑。在开始时,我认为如果孩子没有从父实现虚拟方法,那里会有某种“ hole ”,其中一个方法(或指向方法的指针,或其他)应该是。但接下来会发生的是孩子将使用父母的实施。 谢谢大家,对不起大吼大叫,问一些显然已经在其他地方回答的问题。问题是我应该在给别人的评论给予批准之前阅读更多有关内容如何工作的内容 - 这首先是让我先问这个问题的。 我将来不会重复这个错误。
答案 0 :(得分:3)
这不是正确的问题。正确的问题是,如果子类只覆盖允许覆盖的一个或两个函数,那么问题是"我的子类应该来自父类"。例如,遗传不良是:
class shape
{
public:
virtual void draw();
virtual void print();
};
class log : public shape
{
public:
void print() override;
};
这是一个糟糕的继承,因为这两个都需要一个print方法,但是log类与绘制无关,也与形状有关。它是危险的,不是在安全的情况下,但在某种意义上,使用你的代码的任何人都会非常困惑。
更好的继承的一个例子是:
class shape
{
public:
virtual void draw() = 0;
};
class rectangle : public shape
{
virtual void draw();
};
这里square继承自shape,因为矩形是一个形状,继承强制矩形来定义一个draw方法。通过这种继承,可以清楚地知道发生了什么,并且不存在风险。
答案 1 :(得分:1)
有些孩子实现了父母的虚拟功能,但是 其他一些人只实施一个
这是完全没问题的,virtual
方法与abstract
方法不同的原因之一是前者可选择在更具体的类型(子类)中被覆盖。
我知道我可以实施这些方法,当他们不需要时 可以简单地返回一个例外,或者什么都不做
抛出异常,说没有实施或支持,是个坏主意。如果您知道特定类型不支持特定行为,则该行为不应该是基类本身的一部分。您应该使用接口来实现此类行为(特定于某些派生类)。
答案 2 :(得分:0)
您可能会将虚拟方法与纯虚拟方法混淆。
虚方法只是子类可以覆盖的常规方法,这意味着“交换自定义方法的默认行为”。 你声明他们是这样的:
RewriteCond
另一方面,纯粹的虚拟方法要求您在子类中实现它们。当在父类中不能写出合理的默认行为时,使用它们。如果你没有实现它们,那么子类将无法编译,这很好,因为它可以防止未定义的行为 - 在这种情况下:当提供NO方法时应该运行什么?编译器无法决定。 可以使用以下语法声明它们:
virtual ReturnType myVirtualMethod();
所以我认为你应该问自己的问题是:“我可以提供在大多数情况下适用于此方法的任何默认行为吗?”如果没有,您应该考虑使该方法纯虚拟,否则在父类中实现默认行为,并且不要在不需要它的子类中覆盖该方法。
希望这有帮助!