从具有多重继承的派生类调用所有基类的通用命名方法

Call a common named method of all base classes from a derived class with multiple inheritance

本文关键字:方法 基类 调用 多重继承 派生      更新时间:2023-10-16

我意识到我试图做的事情可能是错误的,所以我很乐意接受和替代方法。下面的所有代码只是一个说明。

假设我有一个派生类,其中包含多个基类:

template<typename... Bases> class Derived : public Bases...{
public:
    VariadicTemplate(BaseClasses&&... base_classes) : BaseClasses(base_classes)... {}
    void DoAllFoo();
};

所有的基类都有一个名为DoFoo()的方法。我打算用一个公共方法Foo()从一个公共基础派生它们:

class CommonBase {
public:
    virtual Foo() { DoFoo() };
protected:
    virtual void DoFoo() = 0;
};
class Base1 : public CommonBase {
    DoFoo() { /* displays something */ };
};
class Base2 : public CommonBase {
    DoFoo() { /* displays something else */ };
};
....

现在这就是我将如何使用它。我想实例化一定数量的派生类对象,用不同的基类指定:

Devired<Base1, Base2> x;
Devired<Base5, Base7, Base21> y;
...
x.DoAllFoo();
y.DoAllFoo();

我希望(以某种方式)派生的DoAllFoo()"迭代"它的基类并调用每个类Foo()方法。

我能想象到的唯一解决方案是在 Derived 中拥有一组函数指针/函子/任何内容,并在构造时让所有 Base 在此集合中注册它们的 Foo() 方法。这可能会起作用,但看起来可以做得更好。

我希望,我不熟悉解决此问题的一些常见模式(或者我只是完全错误),所以请告知。谢谢。

您需要:

void DoAllFoo()
{
    using expand = int[];
    static_cast<void>(expand{ 0, (static_cast<Bases*>(this)->Foo(), void(), 0)... });
}

或:

void DoAllFoo()
{
    using expand = int[];
    static_cast<void>(expand{ 0, (Bases::Foo(), void(), 0)... });
}

取决于对Foo本身的调用是否应该是虚拟的。

我会使用的模式只是组合而不是继承。你为什么不把基类的对象作为你现在称之为Derived的成员呢?您可以简单地将它们存储到std::vector中,然后在DoAllFoo中对其进行迭代。

例如:

class FooWrapper {
// ...
public:
  void DoAllFoos();
private:
  std::vector<std::unique_ptr<CommonBase> > bases_;   

} 
void FooWrapper::DoAllFoos() 
{
   for(auto& base: bases)
     base->DoFoo();
}