2011-03-23 61 views
1

所以我創建了自己的類來保存3D頂點。這基本上是這樣的:C++中的二維數組幫助

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; 
    } 
}; 

現在我需要做的這些二維陣列,但是當我初始化它不會工作。基本上每行都是多邊形的一個面。每列將包含該行的頂點。所以如果一行是

(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]; 

,我得到這個錯誤:

無法從 '頂點(*)[4]' 到 '頂點*'

+0

只是一個旁註。你檢查了[GLM庫](http://glm.g-truc.net/)嗎?我也會推薦[vector](http://glm.g-truc.net/)類,而不是數組。 – Marnix 2011-03-23 18:14:28

+0

[相關常見問題](http://stackoverflow.com/questions/4810664/) – fredoverflow 2011-03-23 18:16:20

回答

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

找到編譯器已經告訴你,你需要知道什麼,只是改變的faces類型:

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

這是否真的做你希望它會做什麼?我試過了: 'int main(int argc,char ** argv){int(* some)[4] = new int [argc] [4]; }' 和它給出了一個編譯器錯誤: TC:在函數 'INT主(INT,字符**)': TC:5:錯誤:從 '詮釋*' 到 'INT' – 2011-03-24 17:20:46

+0

@Frank無效的轉換:你完全確定嗎?我逐字複製了你的代碼片段並且沒有任何問題地編譯它。該錯誤必須在您未發佈的代碼中。 – fredoverflow 2011-03-24 20:13:25

+0

奇怪;對不起 - 昨天肯定有錯別字。再次嘗試,它編譯好。 – 2011-03-25 10:16:06

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

'頂點**'不是一個二維數組。 – fredoverflow 2011-03-23 18:15:54

+0

另外,你爲什麼要從4到3個元素? – fredoverflow 2011-03-23 18:16:54

+0

只是一個錯字。發生在我的鍵盤上的3接近4。 – mkaes 2011-03-23 18:20:56

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> polygon,typedef std::vector<polygon> polyhedron,並自由使用boost::assign中的函數。

0

「二維陣列」是邪惡的...他們通常不會做你想做的事情。

事情是,編譯代碼,它要麼需要把指數週圍,在這種情況下,您可以:

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

或者你不得不使用mkaes發佈的代碼。

問題在於它至少需要4個(如果不是5個)調用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. 一列大小爲num_facesVertex *
  2. num_faces大小爲4Vertex的數組。

然後初始化前者以包含各自的起始地址。爲了「刪除」這個,你需要再次使用C函數free(faces) - 但是對於一次調用就沒有問題。

上述實際上是相當有效的,並且對應於低級表示的那種類型,例如, OpenGL Vertex緩衝區對象用於數據(事實上,它可以與這些對象匹配)。