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

C++ override pure virtual method with pure virtual method

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

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; }
};

两种代码产生相同的效果:class Abstract 是抽象的,你不能实例化它。

然而,这两种形式之间存在语义差异:

  • 第一种形式清楚地提醒 class Abstract 是抽象的(以防万一它的名字不够自言自语 ;-) ).它不仅提醒它:它还通过确保该方法是纯虚拟的来确保它。
  • 第二种形式意味着 class Abstract 完全继承了 Interface 的所有内容。它是抽象的当且仅当它的基础 class 是。

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

  • 第一种形式Abstract仍然是抽象的,不会继承方法的默认实现。
  • 第二种形式确保 Abstract 将继续继承并表现得与 Interface 完全相同。

就我个人而言,我发现第二种形式更直观并且确保了更好的关注点分离。但我可以想象,在某些情况下,第一种形式可能真的有意义。

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

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;
 }

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