使用通用虚函数实现的任意组合实现派生类的正确方法是啥?

Posted

技术标签:

【中文标题】使用通用虚函数实现的任意组合实现派生类的正确方法是啥?【英文标题】:What is the correct way to implement derived classes with arbitrary combinations of common virtual function implementations?使用通用虚函数实现的任意组合实现派生类的正确方法是什么? 【发布时间】:2018-10-30 20:42:20 【问题描述】:

在不复制代码的情况下,用不同的通用成员函数实现组合实现一组派生类的正确方法是什么? WXYZ 类都派生自类 base,因为它们需要能够访问基类中的成员变量。

我知道通过钻石继承来做到这一点,但我怀疑有更好的方法。

class base 
      virtual void f()  /* implementation f_0 */ 
      virtual void g()  /* implementation g_0 */ 
      virtual void h()  /* implementation h_0 */ 
  ;

 class W : public base 
      void g() override  /* implementation g_1 */ 
  ;

  class X : public base 
      void g() override  /* implementation g_1 */ 
      void h() override  /* implementation h_1 */ 
  ;

  class Y : public base 
      void f() override  /* implementation f_1 */ 
      void h() override  /* implementation h_1 */ 
  ;

  class Z : public base 
      void f() override  /* implementation f_1 */ 
      void h() override  /* implementation h_2 */ 
  ;

【问题讨论】:

虚函数必须是纯虚函数吗? *_0 实现是否只是函数的默认实现? 感谢您的建议。我尝试更新示例以改进它,但我想它可能会因反对票而关闭。 【参考方案1】:

使用具有默认实现的中间类:

class base 
public:
    virtual ~base() = default;
    virtual void f() = 0;
    virtual void g() = 0;
    virtual void h() = 0;
;

class derived : public base 
    void f() override  /* implementation f_0 */ 
    void g() override  /* implementation g_0 */ 
    void h() override  /* implementation h_0 */ 
;


class X : public derived 
    void g() override  /* implementation g_1 */ 
;

class Y : public derived 
    void f() override  /* implementation f_1 */ 
;

class Z : public derived 
    void h() override  /* implementation h_1 */ 
;

【讨论】:

感谢您的建议。我尝试更新示例以改进它,但我想这个问题可能会因反对票而关闭。【参考方案2】:

Marc Gregoire 在Professional C++ 的第 10 章中讨论了这个话题。

这是一种使用钻石继承的方法。

  #include <iostream>
  using namespace std;

  struct base 
      virtual void f()  cout << "f_0\n"; /* implementation f_0 */ 
      virtual void g()  cout << "g_0\n"; /* implementation g_0 */ 
      virtual void h()  cout << "h_0\n"; /* implementation h_0 */ 
  ;

  struct f_1 : public virtual base 
      void f() override  cout << "f_1\n"; /* implementation f_1 */ 
  ;

  struct g_1 : public virtual base 
      void g() override  cout << "g_1\n"; /* implementation g_1 */ 
  ;

  struct h_1 : public virtual base 
      void h() override  cout << "h_1\n"; /* implementation h_1 */ 
  ;

  struct h_2 : public virtual base 
      void h() override  cout << "h_2\n"; /* implementation h_2 */ 
  ;


  struct W : public g_1  
      // void g() override  /* implementation g_1 */ 
  ;

  struct X : public g_1, h_1 
      // void g() override  /* implementation g_1 */ 
      // void h() override  /* implementation h_1 */ 
  ;

  struct Y : public f_1, h_1 
      // void f() override  /* implementation f_1 */ 
      // void h() override  /* implementation h_1 */ 
  ;

  struct Z : public f_1, h_2 
      // void f() override  /* implementation f_1 */ 
      // void h() override  /* implementation h_2 */ 
  ;

  int main() 

      cout << "\nW\n";
      W w;
      w.f();
      w.g();
      w.h();

      cout << "\nX\n";
      X x;
      x.f();
      x.g();
      x.h();

      cout << "\nY\n";
      Y y;
      y.f();
      y.g();
      y.h();

      cout << "\nZ\n";
      Z z;
      z.f();
      z.g();
      z.h();
  

输出:

W
f_0
g_1
h_0

X
f_0
g_1
h_1

Y
f_1
g_0
h_1

Z
f_1
g_0
h_2

【讨论】:

以上是关于使用通用虚函数实现的任意组合实现派生类的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法阻止派生类进一步实现虚函数?

多态虚函数表底层实现多重继承的问题及处理

C++每日一问:什么是虚函数?虚函数的实现原理是什么?

在C++中,啥是运算符重载?啥是虚函数?

虚函数和基类中的this指针的问题!

详解C++中基类与派生类的转换以及虚基类