钻石继承 - 调用所有父函数

时间:2017-08-10 07:03:29

标签: c++ inheritance c++17

说我有以下(伪)代码:

class base{
public:
    virtual void callMe() = 0;
    virtual void doRender() = 0;
}

class a : public base{
public:
    virtual void callMe(){/*doA*/} override;
}

class b : public base{
public:
    virtual void callMe(){/*doB*/} override;
}

class myClass : public base, public a, public b{
public:
    virtual void doRender(){
        this->a::callMe();
        this->b::callMe();
    } override;
}

有没有办法以不同的方式写这个?类似的东西:

class myClass : public base, public a, public b{
public:
    virtual void doRender(){
        this->allSupers::callMe();
    } override;
}

我的目标是拥有一个可扩展为具有不同“特征”的基类,所有这些都必须在doRender上执行。

我知道我当然可以通过base中的函数指针列表跟踪这些函数,其中子类在构造时放置它们自己的函数,但我想避免这种情况。必须迭代这些函数仍然在我的最终doRender中至少提供了三行代码。 (或者一条长不可读的线。)

我愿意使用模板提出建议。

2 个答案:

答案 0 :(得分:1)

根据您手头的实际问题,您可以使用mixin风格。基本上,您可以让每个班级在他们自己callMe的结尾(或开头)调用下一个callMe。一个好处是callMe不需要是虚函数。这是一个最小的例子(online):

#include <iostream>

class base
{
public:
    void callMe() {}; // Empty base case
    virtual void doRender() = 0;
};

template <class super>
class a : public super
{
public:
    void callMe()
    {
        std::cout << "doA" << '\n';

        super::callMe(); // Call the next
    };
};

template <class super>
class b : public super
{
public:
    void callMe()
    {
        std::cout << "doB" << '\n';

        super::callMe(); // Call the next
    };
};

template <class super>
class myClass_t : public super
{
public:
    void doRender()
    {
        super::callMe();
    };
};

using myClass = myClass_t<a<b<base> > >; // Defining the order of evaluation;

int main()
{
  myClass m;
  m.doRender();
}

答案 1 :(得分:0)

使用可变参数模板,您可以执行以下操作:

template <typename ... Ts>
class myClassTs : public base, public Ts...
{
public:
    virtual void doRender(){
        (static_cast<void>(Ts::callMe()), ...);
    } override;
}

在C ++ 17中,它将是

xamarin.android