【问题标题】:Allow other base class to implement a virtual function允许其他基类实现虚函数
【发布时间】:2016-10-13 11:01:14
【问题描述】:

是否可以执行以下操作:
我的基类有 3 个纯虚函数。我的派生类实现了这些虚函数中的 2 个,并继承自另一个实现最终第 3 个虚函数的类。

我当前的代码无法编译,所以我认为这是无效的?虽然如果我能以某种方式使用这种方法会很棒。以下是我对这种方法的实际应用/使用。

对我可以用来实现此功能的不同方法有什么建议吗?

class ListBox
{
public:
    virtual void onScroll() = 0;
    virtual void foo() = 0;
    virtual void bar() = 0;
};

class DragScrollHandler
{
public:
    void onScroll()
    {
        ...
    }
};

class HorzListBox: public ListBox, public DragScrollHandler // could also do public HoverScrollHandler, etc.
{
public:
    void foo() override
    {
        printf("foo\n");
    }

    void bar() override
    {
        printf("foo\n");
    }

    HorzListBox()
        : ListBox(), DragScrollHandler()
    {

    }
};

【问题讨论】:

    标签: c++ c++11 multiple-inheritance


    【解决方案1】:

    ListBoxDragScrollHandler先验不同的概念,因此在多重继承之间没有任何联系。我的意思是在以某种方式继承的虚拟onScroll 和另一个不相关(与另一个)分支上的onScroll 实现之间设置链接不是自动的。

    你可以在HorzListBox上定义它来调用继承的实现:

    void onScroll() override {
       DragScrollHandler::onScroll();
    }
    

    这将履行合同:实现抽象并使用继承的实现。

    但最好的方法(在您的情况下)可能是分离概念并拥有Scrollable

    class Scrollable {
    public: 
      virtual void onScroll()=0;
    };
    
    class ListBox: virtual public Scrollable {
    public:
      virtual void foo()=0;
    };
    
    class DragScrollHandler: virtual public Scrollable {
    public:
      void onScroll() override {...}
    };
    
    class HorzListBox: public ListBox, public DragScrollHandler {
    public:
      void foo() override {...}
    };
    

    【讨论】:

      【解决方案2】:

      对我可以用来实现此功能的不同方法有什么建议吗?

      使派生类实现成为另一个基类实现的传递。

      class HorzListBox: public ListBox, public DragScrollHandler
      {
      public:
          void foo() override
          {
              printf("foo\n");
          }
      
          void bar() override
          {
              printf("foo\n");
          }
      
          void onScroll() override
          {
             DragScrollHandler::onScroll();
          }
      
          HorzListBox()
              : ListBox(), DragScrollHandler()
          {
      
          }
      };
      

      【讨论】:

        【解决方案3】:

        对我可以用来实现此功能的不同方法有什么建议吗?

        出于好奇,您可以使用基于 mixin 的方法,如下所示:

        struct ListBox {
            virtual ~ListBox() { }
            virtual void onScroll() = 0;
            virtual void foo() = 0;
            virtual void bar() = 0;
        };
        
        template<typename T>
        struct DragScrollHandler: T {
            void onScroll() override { }
        };
        
        template<typename T>
        struct HorzListBox: T {
            void foo() override { }
            void bar() override { }
        };
        
        int main() {
            ListBox *lb = new HorzListBox<DragScrollHandler<ListBox>>{};
        }
        

        【讨论】:

          【解决方案4】:

          我当前的代码无法编译,所以我认为这是无效的?

          当然它不会编译!不覆盖抽象基类的所有纯虚函数的派生类本身也成为抽象类。这意味着无法实例化派生类,因此会出现编译时错误。

          因此,在您的情况下,HorzListBox 类也是一个抽象类,因为它不会覆盖 ListBox 类的所有 PVF。

          请重新考虑这些行并相应地修改您的代码。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-04-29
            • 2023-02-09
            • 2020-03-04
            • 1970-01-01
            • 1970-01-01
            • 2019-04-14
            • 2016-02-18
            • 1970-01-01
            相关资源
            最近更新 更多