C++ 如何通过具有多重继承的 class 将功能组合并添加到相同的继承方法?
C++ How can I combine and add functionality to the same inherited method by a class with multiple inheritance?
所以说我有 class empire
。 empire
继承了 populationContainer
和 landContainer
:
class empire : public populationContainer, public landContainer
这两个父 class 都有方法 update()
,每个都做自己的事情;例如,人口容器计算人口增长,土地容器计算土地扩张。
我目前无法调用 empire.update()
,因为它不明确。如何同时调用这两种方法?此外,如果我还希望 empire
在 update()
下有更多说明怎么办?
我可以像这样依次调用每个方法:
void empire::update() {
populationContainer::update();
landContainer::update();
// Do other stuff
}
但这不是违反开闭原则吗?如果我想添加更多 'container' class 具有它们自己的 update()
功能怎么办?我必须将每一个都添加到 empire
的 update()
函数中。
我的解决方案是:
// 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 似乎很尴尬。容器的抽象对象类型也太过分了;为什么不具体?
所以说我有 class empire
。 empire
继承了 populationContainer
和 landContainer
:
class empire : public populationContainer, public landContainer
这两个父 class 都有方法 update()
,每个都做自己的事情;例如,人口容器计算人口增长,土地容器计算土地扩张。
我目前无法调用 empire.update()
,因为它不明确。如何同时调用这两种方法?此外,如果我还希望 empire
在 update()
下有更多说明怎么办?
我可以像这样依次调用每个方法:
void empire::update() {
populationContainer::update();
landContainer::update();
// Do other stuff
}
但这不是违反开闭原则吗?如果我想添加更多 'container' class 具有它们自己的 update()
功能怎么办?我必须将每一个都添加到 empire
的 update()
函数中。
我的解决方案是:
// 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 似乎很尴尬。容器的抽象对象类型也太过分了;为什么不具体?