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

Aff*_*Owl 17 c++ abstract-class coding-style interface 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; }
};
Run Code Online (Sandbox Code Playgroud)

与:

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

class Abstract : public Interface {};

class Implementation : public Abstract {
 public:
  int method() override { return 42; }
};
Run Code Online (Sandbox Code Playgroud)

Chr*_*phe 11

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

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

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

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

  • 在第一种形式中Absract保持抽象,不会继承该方法的默认实现.
  • 第二种形式确保Abstact将继续继承并完全表现为Interface.

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


Dal*_*son 6

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

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;
 }
Run Code Online (Sandbox Code Playgroud)

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