我正在学习ECS,现在正在尝试为我的项目实施组件。
因此,根据您的实际情况,我有一个水族馆,里面有很多东西(比如说海藻和鱼)。两者都有年龄,但只有鱼有种族。
我有一个用于一般成分(年龄和其他东西)的类,以及一个与鱼类有关的成分(种族,性别等)的类。
我使用如下所示的create方法制作了一个模板组件类:
template<typename ConcreteComponent> // ConcreteComponent is attached to the class
ConcreteComponent& Components<ConcreteComponent>::create( entity e ) {
m_components.push_back( ConcreteComponent(e) );
return m_components.back();
}
我遇到的问题是,我希望能够根据我拥有的类来调用不同的构造函数(而不是这里的实体e,它对于我的设置中的每个类都是通用的),但同时保持最有效的方式(因此使用模板,每个课程都没有复制粘贴)。对于我的问题,这不是世界末日,但总的来说,如果我再次遇到这个问题,我想做好准备。
是否可以使用不同的参数调用创建函数?
例如:
A<fishComponents> myClassIter;
myClassIter.create("name", age, race, sex)
对于鱼类来说,会将"name",age,race,sex
传递给ConcreteComponent()
的构造函数,而不是仅传递给e
(而且我有"name",age,race,sex
的{{1}}构造函数)。
TL; DR:在模板类方法中,是否可以根据参数将不同数量和值的性质传递给所用类的构造函数
fishComponents
我在C语言中看到了类似的内容,但建议不要触摸它,因为它已过时且不再使用。
答案 0 :(得分:2)
这里的解决方案是使用参数包和std::forward
传递传入实际构造函数的所有参数。下面是一个完整但简化的示例(每种类型都没有数据结构和一个参数):
#include <iostream>
class Fish {
public:
Fish(std::string const &name) {
std::cout << "Making a fish named " << name << '\n';
}
};
class Seaweed {
public:
Seaweed(int length) {
std::cout << "Making a seaweed that's " << length << " feet long\n";
}
};
template <typename ConcreteComponent, typename ...ARGS>
ConcreteComponent create(ARGS && ...args) {
return ConcreteComponent(std::forward<ARGS>(args)...);
}
int main() {
create<Fish>("Bob");
create<Seaweed>(42);
return 0;
}
输出:
$ ./forwarding
Making a fish named Bob
Making a seaweed that's 42 feet long
关于std::forward
值得一读,但是我们在这里基本上要做的是将create
中包含的所有内容都传递给类型的构造函数,同时还要保留类型的属性(例如,是否是临时的)。因此,只要有有效的构造函数将事物传递给您,就可以传递任何东西。
我的代码已经使用C ++ 11、14和17在g ++-7.3.0上进行了测试。
答案 1 :(得分:1)
最好使用面向对象编程中使用的类的继承。
构建基类及其继承的类,以便可以通过其不同的属性动态生成生成的继承类的对象。