C++ 如何通过具有多重继承的 class 将功能组合并添加到相同的继承方法?

C++ How can I combine and add functionality to the same inherited method by a class with multiple inheritance?

所以说我有 class empireempire 继承了 populationContainerlandContainer

class empire : public populationContainer, public landContainer

这两个父 class 都有方法 update(),每个都做自己的事情;例如,人口容器计算人口增长,土地容器计算土地扩张。

我目前无法调用 empire.update(),因为它不明确。如何同时调用这两种方法?此外,如果我还希望 empireupdate() 下有更多说明怎么办?

我可以像这样依次调用每个方法:

void empire::update() {
    populationContainer::update();
    landContainer::update();
    // Do other stuff
}

但这不是违反开闭原则吗?如果我想添加更多 'container' class 具有它们自己的 update() 功能怎么办?我必须将每一个都添加到 empireupdate() 函数中。

我的解决方案是:

// If you add more base classes here, add them also to the 'update' method
class empire : public populationContainer, public landContainer

您需要在某处保存更新函数列表,例如,它可能位于虚拟基础 class IUpdatable 中,它保护了 RegisterUpdateFunc(lambda) 方法和 public Update() 方法一个接一个地调用所有已注册的 lambda。

现在每个继承此class并想参与“更新事件”的人只需在他的构造函数中调用一次

RegisterUpdateFunc([=](){ Update(); })

OO,尤其是 C++ 的默认对象模型,并不能解决所有问题。

如果您有一个对象是其他类型对象的容器的产物,并且您希望能够将一组操作分派给它的每个部分,那么内置的 C++ 对象模型对您帮助不大.

有几种方法。

首先,可以等待编译时反射。那是几年了。

其次,您可以使用代码生成。 Qt 将其与其 MOC 一起使用。

第三,你可以要求一个中心点,帝国 class 定义它是什么产品:

static auto asProduct(auto&& self){
  return std::forward_as_tuple( get<Base1>(decltype(self)(self), get<Base2>(decltype(self)(self), etc );
}

第三,你可以使用CRTP从Derived和一个碱基列表中生成上面的asProduct

第四,您可以生成 Empire class(或基本元容器),其中包含连接方法和容器的列表。这基本上就是编写自己的对象模型。

第五,你可以手动转发update里的东西。


在相关问题中,is-a 在这里似乎被过度使用了。你的帝国有土地和人口。在这里使用 is-a 似乎很尴尬。容器的抽象对象类型也太过分了;为什么不具体?