C ++在数组中存储任何子结构/类?

时间:2013-04-18 03:20:16

标签: c++

在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 ++中必须有一种简单的方法来实现它。

3 个答案:

答案 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()) );