允许其他基类实现虚函数

时间:2016-06-13 06:04:24

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

是否可以执行以下操作:
我的基类有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()
    {

    }
};

4 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分: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()
    {

    }
};

答案 2 :(得分:2)

  

我可以使用不同方法的任何建议来实现此功能吗?

为了好奇,您可以使用基于 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>>{};
}

答案 3 :(得分:-1)

  

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

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

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

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