在C ++中我定义了一系列结构......
struct Component {};
struct SceneGraphNode : Component {};
struct Renderable : Component {};
struct Health : Component {};
这些很容易成为课程,我被告知C ++的差别很小。
在Java中,可以声明类型为Component
的数组,并将任何从(继承)Component
扩展的类放入其中。 Java将它们视为所有组件,并且由于所有组件都使用智能指针,因此Java的“数组”实际上只是一个智能指针列表,它们的大小都相同。
但是我知道Java处理的数组与C ++有很大不同。当我检查每个结构的大小时,我得到了以下内容。
Component // 4
SceneGraphNode : Component // 8
Renderable : Component // 8
Health : Component // 20
这并不令人惊讶。现在,当我创建一个组件数组时,块的大小显然将是4(字节),这将不包含任何其他结构。
所以我的问题是,如何存储Components
的松散列表(IE是一个可以存储从Component继承的类/结构的列表)?在Java中,这简直令人难以置信。当然,在C ++中必须有一种简单的方法来实现它。
答案 0 :(得分:2)
您可以拥有指向子类对象的Base类指针,即
Component * sgn = new SceneGraphNode
因此,分配一个Component*
s数组(或者如果需要改变大小的向量),并使每个入口指向派生对象。
Component * components[100];
components[0] = new SceneGraphNode;
components[1] = new Renderable;
// so on and so on
除此之外,您必须在Component中具有要在子类中定义的任何成员函数的虚函数
class Component {
public:
virtual void method() = 0;
virtual int method2(int arg) = 0;
};
class SceneGraphNode : public Component {
public:
virtual void method(){
//body
}
virtual int method2(int arg){
return arg*2;
}
};
virtual
关键字使得它在运行时查看指向对象的实际类型并调用其方法,而不是调用指针类型方法。这就是java正常工作的方式。 = 0
使函数“纯虚拟”意味着子类必须定义该方法。使用上面定义的数组......
components[0]->method();
compenents[2]->method2(1);
如果您希望向量到数组,可以使用以下代码替换数组版本:
#include <vector>;
//...
std::vector<Component* > components;
components.push_back(new SceneGraphNode);
components.push_back(new Renderable);
答案 1 :(得分:1)
将它们存储如下
std::vector<Component *> components;
Component * c = new Health;
components.push_back( c );
调用components[0] -> method();
将调用method()
Health
这就是在C ++中完成多态的方式。
还要确保Component的method()
为virtual
答案 2 :(得分:1)
您可以存储指向基类对象的vector
智能指针,然后您可以将派生类对象添加到其中。
例如:
std::vector<std::unique_ptr<Component> > base;
Component.push_back( std_unique_ptr<Component>(new SceneGraphNode()) );
//^^use correct constructor, this example just show the methodology
Component.push_back( std_unique_ptr<Component>(new Renderable()) );