C ++使用纯虚方法覆盖纯虚方法

时间:2015-04-17 19:51:06

标签: c++ interface coding-style abstract-class pure-virtual

用另一个纯虚方法覆盖纯虚方法是否有意义?是否有任何功能差异或代码风格的原因,而不是选择以下选项之一?

class Interface {
 public:
  virtual int method() = 0;
};

class Abstract : public Interface {
 public:
  int method() override = 0;
};

class Implementation : public Abstract {
 public:
  int method() override { return 42; }
};

对战:

class Interface {
 public:
  virtual int method() = 0;
};

class Abstract : public Interface {};

class Implementation : public Abstract {
 public:
  int method() override { return 42; }
};

2 个答案:

答案 0 :(得分:10)

两个代码产生相同的效果:类Abstract是抽象的,您无法实例化它。

但是这两种形式之间存在语义差异:

  • 第一种形式清楚地提醒,班级Abstract是抽象的(以防万一它的名字不能自我展示 ;-))。它不仅提醒它:它还通过确保方法是纯虚拟来确保它。
  • 第二种形式意味着班级Abstract完全从Interface继承了所有内容。当且仅当它的基类是时,它是抽象的。

这会对您未来的代码演变产生影响。例如,如果有一天你改变主意并希望界面具有method()的默认实现:

  • 在第一种形式中,Absract仍然是抽象的,不会继承该方法的默认实现。
  • 第二种形式可确保Abstact继续继承,其行为与Interface完全相同。

我个人发现第二种形式更直观,可以更好地分离关注点。但我可以想象,可能有一些情况,第一种形式真的有意义。

答案 1 :(得分:5)

方法的纯规范强制覆盖,但它不会阻止您提供该方法的实现。以下是一种罕见但有时有用的技术。

class Interface
{
   virtual void method() = 0;
};

class Abstract : public Interface
{
   virtual void method() = 0;
}
inline void Abstract::method() 
{ 
    do something interesting here;
}

class Concrete : public Abstract
{
   virtual void method();
}

inline void Concrete::method()
{
    // let Abstract::method() do it's thing first
    Abstract::method();
    now do something else interesting here;
 }

如果有几个派生自Abstract的类需要一些常用功能,但有时需要添加特定于类的行为,这有时很有用。 [并且应该被迫提供这种行为。]