2

在 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的列表(即一个可以存储从 Component 继承的任何类/结构的列表)?在 Java 中,这非常简单。当然,在 C++ 中必须有一种简单的方法来做到这一点。

4

3 回答 3

2

您可以有一个指向子类对象的基类指针,即 Component * sgn = new SceneGraphNode

所以分配一个 s 数组Component*(或者一个向量,如果它需要改变大小)并使每个入口点指向一个派生对象。

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);
于 2013-04-18T03:26:00.440 回答
1

您将它们存储如下

std::vector<Component *> components;
Component * c = new Health;
components.push_back( c );

调用 components[0] -> method();method()调用Health

这就是 C++ 中多态性的实现方式。

还要确保method()Component 是virtual

于 2013-04-18T03:24:49.123 回答
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()) );
于 2013-04-18T03:25:32.270 回答