用纯虚拟覆盖虚拟......可以吗?
Posted
技术标签:
【中文标题】用纯虚拟覆盖虚拟......可以吗?【英文标题】:Overriding virtual with pure virtual..Is it ok? 【发布时间】:2012-09-09 23:33:07 【问题描述】:例子:
class IGui
protected:
virtual bool OnClicked()return false;
virtual bool OnHover()return false;
virtual bool OnScrollBarChange()return false;
virtual bool OnTextChange()return false;
...
class IGuiButton: public IGui
protected:
virtual bool OnClicked() = 0;
virtual bool OnHover()
do stuff
return true;
...
关键是为所有可能的 gui 类型提供一个通用接口(并非所有虚拟都需要被覆盖),然后为按钮提供一个精简的专业化,但对于按钮,必须有一个覆盖OnClicked..
另外,我认为我应该让那些按钮不应该覆盖私有(所以使用私有继承,并使用花哨的“使用 Base::Method;”来保护特定的按钮?
【问题讨论】:
你可以试一试看看,还是你在问它是否是一个好的设计? @John3136,是的,我正在寻找建议,我有点习惯于对我的实施选择感到沮丧._. 通用接口的用例是什么? 【参考方案1】:这个问题有多个方面。第一个其实是一个很有趣的问题:
派生类可以有一个在基类中不纯的纯虚方法吗?
答案是是的,可以。使用预期的(如果您希望这样做)语义:从中间类型派生的类型必须实现虚函数而不是抽象类型。这导致了一个奇怪的情况,其中基不是抽象的,但派生类型是......这将是令人惊讶的。为此,我会在设计中避免这种情况。
您是否应该将派生类型不应覆盖的成员标记为
private
?
不,这样做没有任何理由或优势。无论成员函数是public
、protected
还是private
派生类都可以覆盖它。任何可以通过基类型调用函数的代码仍然可以通过转换为基类型来调用它。这会导致您的设计中出现另一个奇怪的东西。基类填充了protected
虚函数,这意味着它们只能由派生类型访问。这没有定义接口,不能这样使用。如果函数/类引用IGui
或IGuiButton
,它将无法做很多事情,因为没有公共接口。这基本上意味着没有人能够调用任何事件——除非你还滥用友谊来提供对事件处理程序的访问,但你应该避免它。
那么什么是合适的设计?
有不同的选择。我建议在创建自己的方形***之前,先看看过去发明的那些***:查看不同的图形框架和库,并尝试理解他们为什么决定这样设计它们。查看差异并尝试确定它们带来的优势/劣势以及哪个选项与您的问题相匹配。 UI 是一个拥有大量现有技术的领域,你可能不会从头开始设计比该领域的人过去所做的更好的东西——你可能会这样做,但更容易陷入其他人以前也遇到过同样的陷阱。
【讨论】:
【参考方案2】:我不得不说我认为你试图做的是糟糕的设计。
您的***(IGui)“拥有一切”,然后您在向下移动类层次结构时有效地取出东西。顶层通常有共同的东西,你在向下移动时添加差异。
你正在失去一个好的设计能给你的保护。
【讨论】:
问题是实际处理 gui 事件的方法(不是我的)在单个函数调用中处理所有内容,它会为您提供它的数据类型和 gui ID。这很糟糕,因为它不是面向对象的。我试图做的是通过为中心类提供具有行为的分隔 gui 对象来使创建 gui 的东西更加模块化。 更多关于我所做的选择,我对 IGui 类的想法实际上是为所有可能存在的 gui 元素创建一个接口,而不是真正的基类。它并不全是纯粹的,因为一个元素不会使用所有东西。以上是关于用纯虚拟覆盖虚拟......可以吗?的主要内容,如果未能解决你的问题,请参考以下文章