使用纯虚拟覆盖虚拟..这样可以吗?

时间:2012-09-09 23:33:08

标签: c++ inheritance pure-virtual

示例:

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类型都有一个commom接口(不需要覆盖所有虚拟内容),然后为按钮提供lite特化,但对于按钮,theres必须是一个覆盖OnClicked ..

另外,我认为我应该使那些按钮不应该覆盖私有(所以使用私有继承,并使用那个花哨的“使用Base :: Method;”来使特定的保护?

2 个答案:

答案 0 :(得分:5)

问题有多方面。第一个实际上是一个非常有趣的问题:

  

派生类是否可以在基础中使用纯粹的虚方法?

答案是,它可以。有了预期的(如果你期望这个工作)语义:从中间类型派生的类型必须实现虚函数不是抽象类型。这导致了一个奇怪的情况,其中基础不是抽象的,但派生类型是......这将是令人惊讶的。就此而言,我会在设计中避免这种情况。

  

如果您标记为private,那么派生类型的成员不应该覆盖?

不,这样做是没有理由或优势的。成员函数是publicprotected还是private派生类可以覆盖它。任何可以通过基类型调用函数的代码仍然可以通过强制转换为base来调用它。这会在您的设计中导致另一个奇怪的事物。基类填充了protected个虚函数,这意味着它们只能由派生类型访问。这不会定义接口,也不能这样使用。如果函数/类引用IGuiIGuiButton,则它将无法执行任何操作,因为没有公共接口。这基本上意味着没有人能够调用任何事件 - 除非你也滥用友谊来提供对事件处理程序的访问,但是你应该避免它。

  

那么什么是合适的设计?

有不同的选择。我建议在创建自己的方形轮之前,先看看过去发明的那些轮子:查看不同的图形框架和库,并尝试理解他们为什么决定这样设计它们。查看差异并尝试确定它们带来的优势/劣势以及哪个选项符合您的问题。 UI是一个有很多现有技术的领域,你有可能不会从头开始设计比过去的人更好的设计 - 你可能会这样做,但它更容易陷入其他人都感受到的相同陷阱。

答案 1 :(得分:0)

我不得不说我认为你要做的就是糟糕的设计。

你的顶级(IGui)“拥有一切”,然后当你向下移动类层次结构时,你正在有效地拿出东西。顶级通常会有常见的东西,你可以在向下移动时添加差异。

你正在失去一个好的设计可以给你的保护。