2016-05-15 18 views
-1

Ich möchte jetzt, wenn es möglich ist, und schließlich, wie es möglich ist, eine Klasse auf eine besondere Art und Weise zu implementieren, so dass Sie einen Vektor dieser Klasse erstellen können und nach dem Ausfüllen, durchlaufen die Klassenattribute ohne Iteration des Vektors.C++ Klasse Speicherlayout

Dies ist ein Beispiel:

class Vertex3f 
{ 
    public: 
     union 
     { 
      float vec[3]; 
      struct 
      { 
       float x, y, z; 
      }; 
     }; 

    public: 
     Vertex3f(); 
     ~Vertex3f(); 

    ... 
} 

Dann eine std::vector dieser Klasse erstellen, füllen Sie es und Zugang alle Instanzen Klassenattribute:

Vertex3f v1, v2; 
v1.x = 10.0f; 
v1.y = 0.0f; 
v1.z = 5.0f; 
v2.x = 8.0f; 
v2.y = -5.0f; 
v2.z = 3.0f; 

// Create and fill the vector 
std::vector<Vertex3f> vec; 
vec.push_back(v1); 
vec.push_back(v2); 

// Get all the vertices data in one go 
// This is the tricky part I'm not sure it can be done 
size_t size = vec.size() * (sizeof(float) * 3); 
float* vertices = new float[size]; 
memcpy(vertices, &vec[0].x, size); 

ich jetzt, dass die Bullet Physics Bibliothek tut so etwas aus Leistungsgründen und ich würde gerne dasselbe machen, aber ich verstehe nicht wie.

+1

Es gibt ein kleines Problem mit Ihrem Code: Es gibt keine Garantie, dass 'float vec [3]' und Ihre Struktur die gleiche Größe haben. Wenn der systemeigene Compiler-Padding für ein System 64-Bit ist, ist die Struktur doppelt so groß wie das Array. –

+2

Sie sollten wahrscheinlich herausfinden, was C++ über [POD-Typen] (http://en.cppreference.com/w/cpp/concept/PODType) und [Speicherausrichtung] sagt (http://stackoverflow.com/q/5435841)/3344612) – teivaz

+0

Genau darum ging es mir. 'float vec [3]' hat nicht die gleiche Größe wie meine Klasse, da die Klasse auch Mitgliedsfunktionen und andere Attribute enthält. – zeb

Antwort

0

Wenn Sie nur die Funktionalität möchten, habe ich eine andere Implementierung, die für Sie arbeiten kann.

Sie können Ihr Array von Schwimmern erstellen und dann Ihrer vec3-Klasse einen Zeiger auf die x-Position des entsprechenden Punkts in diesem Vektor geben.

Etwas wie:

class vec3 
{ 
public: 
    vec3(float* valN) 
    { 
     val = valN; 
    } 

    float x() 
    { 
     return *val; 
    } 
private: 
    float* val; 
}; 

int size = 3; 
float* fArr = (float*)malloc(sizeof(float)*size); 

fArr[0] = 8; 
fArr[1] = 9; 
fArr[2] = 10; 

std::vector<vec3> points; 
vec3 p(&fArr[0]); 

points.push_back(p); 

float out = points[0].x(); 

aus als 8.0 hier landen sollte.

+0

Ja, ich könnte dies tun, aber über' Std denken: : vector 'für' fArr' würde dies unbrauchbar machen, weil 'std :: vector' Dinge im Speicher bewegt, wenn Sie Elemente hinzufügen/entfernen, und ich möchte die Möglichkeit behalten, Scheitelpunkte zu meinem Mesh hinzuzufügen/zu entfernen. Auch auf diese Weise muss ich immer 'float' Array als Unterstützung haben, auch wenn ich nur ein einfaches' vec3' benötige, um einige Berechnungen durchzuführen – zeb

+0

Wenn Sie dem Vektor vorher mit vec.resize() Speicher zuweisen, können Sie das Problem vermeiden mit bewegender Erinnerung herum. Es wäre auch ziemlich einfach, den vec3-Konstruktor zu überladen, damit er ein eigenes Array erstellen kann. –

+0

Ja, das scheint machbar. Ich werde es versuchen – zeb