我希望能够遍历从共同祖先继承的类列表。
我想要的缩小版本(类似Python的语法,因为我来自的语言):
int outcome = 0;
PlayerTypeOne player_one();
if doThingWithPlayer(player_one, some, other, variables){
outcome++;
}
PlayerTypeTwo player_two();
if doThingWithPlayer(player_two, some, other, variables){
outcome++;
}
PlayerTypeThree player_three();
if doThingWithPlayer(player_three, some, other, variables){
outcome++;
}
如果这不是进行此类操作的首选方式,那么非常欢迎有关我应该如何继续的建议。
我想避免的代码是:
<button>
答案 0 :(得分:1)
您正在寻找factory design pattern:
Player *create_by_name(const std::string &what)
{
if (what == "PlayerTypeOne")
return new PlayerTypeOne;
if (what == "PlayerTypeTwo")
return new PlayerTypeTwo;
// ...
}
等等。您似乎也想要做的是为每个子类的构造函数提供参数。
如果所有子类都使用相同的构造函数参数,则这变得微不足道:将参数传递给工厂,并将它们转发给构造函数。
如果需要为构造函数支持不同的参数,这会变得更加复杂。我建议你从小开始,为你的对象实现一个简单的工厂,没有构造函数参数,或者只有几个对所有子类都相同。一旦你掌握了基本原理,你就可以担心处理复杂的角落案例。
然后,只需要一个类名数组,遍历数组,然后调用工厂。这应该与伪Python代码具有相似的结果。
答案 1 :(得分:1)
C ++没有提供内置的内省,所以你不能只获取代表你的类的对象并用它们创建实例。
你可以做的是使用元编程:
// A list of types
template <class...> struct pack { };
// Calls f with one default-constructed instance of each T
template <class... Ts, class F>
void construct_each(pack<Ts...>, F &&f) {
// Classic pre-C++17 expansion trick
using ex = int[];
(void)ex{(f(Ts{}), void(), 0)..., 0};
// C++17 version
// (void)(f(Ts{}), ...);
}
// ...
using Players = pack<PlayerTypeOne, PlayerTypeTwo, PlayerTypeThree>;
void foo() {
int outcome = 0;
construct_each(Players{}, [&](auto &&player) {
if(doThingWithPlayer(player, some, other, variables))
++outcome;
});
}