C ++中的2D数组帮助

时间:2011-03-23 18:02:32

标签: c++ opengl multidimensional-array

所以我创建了自己的类来保存3D顶点。这基本上看起来像:

class Vertex                                    // Vertex Class
{
public:
    float x;                                // X Component
    float y;                                // Y Component
    float z;                                // Z Component

    float getX() {
        return x;
    }
    float getY() {
        return y;
    }
    float getZ() {
        return z;
    }
};

现在我需要制作这些的2D数组,但是当我初始化它时它将无法工作。基本上每行都是多边形的一个面。每列将包含该行的顶点。所以如果一行是

(0,0,0)(1,1,1)(3,3,3)(4,4,4);

然后该行将代表具有顶点(0,0,0)(1,1,1)(3,3,3)(4,4,4)的面;

现在我尝试使用

初始化它
Vertex faces = new Vertex[num_faces][4];

工作。这看起来很简单,所以我做错了什么?

编辑:我把它改成了

Vertex *faces = new Vertex[num_faces][4];

我收到此错误:

无法从'Vertex(*)[4]'转换为'Vertex *'

4 个答案:

答案 0 :(得分:3)

cannot convert from 'Vertex (*)[4]' to 'Vertex *'

编译器已经告诉您需要知道的内容,只需更改faces的类型:

Vertex (*faces)[4] = new Vertex[num_faces][4];

答案 1 :(得分:0)

您需要为要存档的内容声明二维数组。

Vertex **faces = new Vertex*[num_faces];
for(int i=0; i < num_faces; ++i)
    faces[i] = new Vertex[4];

当然,当num_faces是编译时常量时,你可以像这样声明数组。

Vertex faces[num_faces][4];

可以在c++-faq lite

中找到具有多个维度的动态数组的良好资源

答案 2 :(得分:0)

当向量执行相同的操作时,永远不要使用数组。您需要的数据结构是std::vector<std::vector<Vertex> >

class Vertex {
    ...
    Vertex(float x, float y, float z) : x(x), y(y), z(z) {}
};

int main() {
    // a 1D array of vertices is a polygon
    std::vector<Vertex> square;
    square.push_back(Vertex(0, 0, 0));
    square.push_back(Vertex(0, 1, 0));
    square.push_back(Vertex(1, 1, 0));
    square.push_back(Vertex(1, 0, 0));

    // Another square, in a different plane
    std::vector<Vertex> square1;
    square1.push_back(Vertex(0, 0, 1));
    square1.push_back(Vertex(0, 1, 1));
    square1.push_back(Vertex(1, 1, 1));
    square1.push_back(Vertex(1, 0, 1));

    // A 2D array of vertices is a polyhedron.
    std::vector<std::vector<Vertex> > cube;
    cube.push_back(square);
    cube.push_back(square1);
    // need four more sides
}

请注意完全没有指针,mallocnew

为了提高可读性,我建议使用typedef std::vector<Vertex> polygontypedef std::vector<polygon> polyhedron,并自由使用boost::assign中的函数。

答案 3 :(得分:0)

“二维阵列”是邪恶的...他们通常不会做你希望实现的目标。

事情是,为了编译你的代码,它需要转换索引,在这种情况下你得到:

Vertex *faces[4] = {
    new Vertex[num_faces],
    new Vertex[num_faces],
    new Vertex[num_faces],
    new Vertex[num_faces]
};

或者您必须使用mkaes发布的代码。

这个问题是它需要至少四次(如果不是五次)调用new(),其中任何理论上都可能失败。你也不能在一次操作中delete这个“东西”。

对于像这样的完全“类似结构”的对象,可以执行以下技巧:

char *memblk =
    malloc(num_faces * 4 * sizeof(Vertex) + num_faces * sizeof(Vertex *));

Vertex **faces = static_cast<Vertex **>memblk;
Vertex *first = static_cast<Vertex *>(memblk + num_faces * sizeof(Vertex *));

for(i = 0; i < num_faces; first += 4, i++)
    faces[i] = first;

您可以在其中分配足够大的单个内存块来保存:

  1. 大小为Vertex *的{​​{1}}数组,
  2. num_faces num_faces大小为Vertex的数组。
  3. 然后初始化前者以包含相应的起始地址。

    要“删除”此功能,您需要再次使用C函数4 - 但只需一次调用即可。

    以上实际上是非常有效的,并且与例如低级别表示形式紧密对应。 OpenGL顶点缓冲区对象用于数据(实际上,它可以与之匹配)。