是否可以在C ++中将派生类数组截断为基类数组?

时间:2011-02-07 20:38:55

标签: c++ arrays class opengl casting

我正在创建一个使用OpenGL的应用程序,并且当前存储的对象数组应该呈现每个框架,如下所示:

class Object {
  private:
    float x;
    float y;
  public:
    void func1();
    void func2();
    ...
};

我希望能够从这些对象的数组中创建一个顶点缓冲区对象,但我不能简单地传递数组,因为该类包含glBufferData不期望的附加函数。

是否可以像这样分离对象类:

class baseObject {
  public:
    float x;
    float y;
};

class derivedObject : public baseObject {
  public:
    float x;
    float y;
    void func1();
    void func2();
    ...
};

然后使用derivedObjects或其他方式将baseObjects数组转换为static_cast数组,然后将其传递给glBufferData?或者是迭代对象数组的唯一方法,将xy变量提取到一个单独的数组中,然后可以传递给glBufferData

4 个答案:

答案 0 :(得分:2)

Object中的函数实际上并没有对对象的布局做出任何贡献。尽管规范并不能保证这一点,但在所有主要编译器中,对象的内存中表示只是其字段。 (但是,如果在混合中添加虚拟函数,则不是这样)。在您的情况下,您的Object类在内存中看起来与此struct无法区分:

struct JustObjectFields {
    float x, y;
};

因为当您删除成员函数时,这就是您剩下的内容。

这样做的原因是成员函数通常被编译为常规函数,这些函数将this指针作为显式的第一个参数。此代码与类的任何一个实例分开,因此类大小不受它们的影响。简而言之,您应该能够在不使用继承的情况下执行此操作。只需使用您的原始Object类。

答案 1 :(得分:0)

您可以创建一个基类指针数组,并手动将它们指向派生类数组中的元素。但是,您不能对数组本身进行任何类型的花式转换,因为数组偏移取决于知道每个元素的实际大小。使用指针,这不是问题,但是对于数组中的实际实例,当您尝试使用错误类型的指针访问单个元素时,会遇到大量崩溃。

答案 2 :(得分:0)

阵列的类型转换在这种情况下不起作用 - http://codepad.org/6DFLPPDH
通常,不可能将派生对象数组转换为 没有移动数据的基础对象数组,我想没人会打扰 特别支持派生类只添加方法的情况 实际上,即使数组指针转换也不是很可靠 - http://codepad.org/15a4cCy9
但是用简单的指针肯定不是问题 - http://codepad.org/4vEK5wY1
在你的情况下,无论如何它应该没问题,我想。

答案 3 :(得分:0)

简短回答:是的。如果glBufferData接受baseObject作为参数,则也可以使用derivedObject,因为类derivedObject的实例也是类baseObject的实例。

这里的问题不是方法/功能,而是数据。 glBufferData期望将类baseObject的实例作为参数,因为该方法需要一个对象,其中包含baseObject中描述的数据成员。 Object作为参数无效,因为其数据成员可能与baseObject不同。如果方法被传递给具有无效数据的对象,这可能是灾难性的。

但是,通过将derivedObject定义为继承自baseObject,我们说derivedObject IS a baseObject plus derivedObject定义中列出的所有数据成员。因此,当我们将derivedObject的实例传递给glBufferData时,它可以将其视为baseObject的实例而没有危险。