PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bin ich jetzt doof, oder was?


liquid
2003-02-05, 18:39:21
Hmm, irgendwie hab ich heut nen' Schaden.
Warum geht das hier?


GLfloat array[3] = {0.5f, 0.5f, 0.0f};

basic_vector vec0(array);


Aber das hier überhaupt nicht?

basic_vector vec0({0.5f, 0.5f, 0.0f});


Kommt doch prinzipiell aufs selbe raus, oder nicht?

cya
liquid

firewars
2003-02-05, 18:45:00
Bin mir zwar nicht sicher, aber hast du mal


basic_vector vec0(0.5f,0.5f,0.0f);


ausprobiert?

liquid
2003-02-05, 18:49:44
Sicher, das funzt perfekt, aber das ist ja auch nicht mein Problem.
Ein kleiner Ausschnitt aus dem basic_vector Header...


class basic_vector
{
public:
// constructors
basic_vector();
basic_vector(basic_vector* vec); // use this with caution
basic_vector(const GLfloat& x, const GLfloat& y, const GLfloat& z);
basic_vector(const GLfloat* array_ptr);
basic_vector(GLfloat* array_ptr);

~basic_vector(); // destructor

basic_vector(const basic_vector& rhs); // copy-contructor

// operators
basic_vector& operator=(const basic_vector& rhs);
...


Ich will die Werte aber auch als Array übergeben können und dafür hab ich auch extra einen passenden Konstruktor geschrieben, aber wie gesagt, er tut es nich... *grrr*

cya
liquid

Demirug
2003-02-05, 19:21:00
Das ist eine der Stellen wo C++ nicht durchgängig ist.

Konstrukte der Art {0.5f, 0.5f, 0.0f} lassen sich nur zur Initalisierung von Arrays benuten. Wenn man aber nun ein Array als Parameter übergeben will geht das nicht.

Damit muss man leben.

Abe Ghiran
2003-02-05, 19:28:26
Also unter java könnte man

basic_vector vec0(new Float[]{0.5f, 0.5f, 0.0f});

schreiben. Unter c/c++ wird das aber meiner Meinung nach nie funktionieren, da die Sprachen das in ihrer Grammatik gar nicht ausdrücken können. Das was du geschrieben hast, sieht ja für den Compiler aus wie ein Block.
Der java Compiler erkennt am "new foat[]" das hier on the fly ein float array angelegt wird und kann dann die "{}" korrekt als initalisierung eines arrays übersetzen. Unter c / c++ gibt es ja aber gar keine "array versionen" der Datentypen, dort kommen ja die "[]" hinter den Vaiablennamen. Das einzige was dann funktionieren könnte, wäre

basic_vector vec0(float f[]={0.5f, 0.5f, 0.0f});

aber auch das kann ich mit dev-c++ nicht übersetzen.

Grüße, Jan

edit: Demirug war schneller, das kommt davon wenn man parallel zum posten Simpsons guckt :)

zeckensack
2003-02-05, 20:39:18
Ich glaube zwar nicht, daß dir das weiterhilft, aber ich schlage mal drei Änderungen vor:
class basic_vector
{
public:
// constructors
basic_vector();
// basic_vector(basic_vector* vec); // don't use this at all! just dereference and use the regular copy constructor
basic_vector(const GLfloat x, const GLfloat y, const GLfloat z);
basic_vector(const GLfloat* const array_ptr);
basic_vector(GLfloat* array_ptr);

~basic_vector(); // destructor

basic_vector(const basic_vector& rhs); // copy-contructor

// operators
basic_vector& operator=(const basic_vector& rhs);
...

liquid
2003-02-05, 21:21:56
Originally posted by zeckensack
Ich glaube zwar nicht, daß dir das weiterhilft, aber ich schlage mal drei Änderungen vor:
class basic_vector
{
public:
// constructors
basic_vector();
// basic_vector(basic_vector* vec); // don't use this at all! just dereference and use the regular copy constructor
basic_vector(const GLfloat x, const GLfloat y, const GLfloat z);
basic_vector(const GLfloat* const array_ptr);
basic_vector(GLfloat* array_ptr);

~basic_vector(); // destructor

basic_vector(const basic_vector& rhs); // copy-contructor

// operators
basic_vector& operator=(const basic_vector& rhs);
...


Zum ersten: deswegen auch "use with caution" *g* - ich hätte es am Ende sowieso entfernt, aber danke für die Warnung.

2. Warum keine Referenzen nehmen zecki? Oder lohnt sich das nicht wegen irgendwelchem ominösen Overhead? Bitte um Erklärung *büddde*

3. Hatte ich auch schon im Sinne, wird sogleich geändert!

Sonst muss ich es halt so lassen wie bisher und mir was anderes einfallen lassen. Mal sehen...

cya
liquid

zeckensack
2003-02-05, 21:47:36
Originally posted by liquid


Zum ersten: deswegen auch "use with caution" *g* - ich hätte es am Ende sowieso entfernt, aber danke für die Warnung.

2. Warum keine Referenzen nehmen zecki? Oder lohnt sich das nicht wegen irgendwelchem ominösen Overhead? Bitte um Erklärung *büddde*

3. Hatte ich auch schon im Sinne, wird sogleich geändert!

Sonst muss ich es halt so lassen wie bisher und mir was anderes einfallen lassen. Mal sehen...

cya
liquid

2. Ominöser Overhead: Referenzen sind (Compiler-intern, nicht syntaktisch) Zeiger ;)
Bei Typen, die sowieso nur 32 bit groß sind, und bei gut funktionierender Optimierung in Registern übergeben werden können, bringen Referenzen nur zusätzlichen Speichertraffic.

Das bringt uns auch zu Punkt 1:
Wenn ich einen Zeiger dereferenziere, erzeuge ich ja quasi ein Objekt und blase den Speicherverbrauch auf.
Wenn ich einen derefernzierten Zeiger aber als Referenz benutze, passiert - nichts. Es muß kein temporäres Objekt erzeugt werden.

Bspstruct Banane
{
int schale;
int aufkleber;
};

Banane b={0,0}; //Banane erzeugen
Banane* bp=&b; //Zeiger auf Banane
Banane bananen_kopie=*bp; //Banane kopieren
Banane& c=*bp; //Bananen-Referenz
c ist Compiler-Intern vom gleichen Typ wie bp. Statt der Dereferenzierung wird einfach nur der Zeiger kopiert.

Da über seperate Konstruktoren eine Unterscheidung einzuführen, bringt nichts.

liquid
2003-02-05, 21:52:04
Thx, gut zu wissen, wieder was dazu gelernt! :)

Xmas
2003-02-05, 21:58:14
Originally posted by zeckensack
Das bringt uns auch zu Punkt 1:
Wenn ich einen Zeiger dereferenziere, erzeuge ich ja quasi ein Objekt und blase den Speicherverbrauch auf.

Nur durch das dereferenzieren des Pointers wird nicht mehr Speicher benötigt.

Ob der Konstruktor nun

basic_vector(basic_vector* vec) { vec->x = 1; }

oder

basic_vector(basic_vector& vec) { vec.x = 1; }

ist, macht praktisch keinen Unterschied. Einzig

basic_vector(basic_vector vec) { vec.x = 1; }

ist nicht empfehlenswert, da hier das Objekt tatsächlich kopiert wird ("Call by Value").

zeckensack
2003-02-05, 22:06:51
Originally posted by Xmas

Nur durch das dereferenzieren des Pointers wird nicht mehr Speicher benötigt.Stimmt, die Formulierung war zu holprig. Genauer wäre gewesen "Das Verwenden eines dereferenzierten Zeigers als temporäres Objekt" oder sowas in der Art :|

Ob der Konstruktor nun

basic_vector(basic_vector* vec) { vec->x = 1; }

oder

basic_vector(basic_vector& vec) { vec.x = 1; }

ist, macht praktisch keinen Unterschied.Genau das habe ich doch gesagt (jedenfalls wollte ich das sagen) :)
Einzig

basic_vector(basic_vector vec) { vec.x = 1; }

ist nicht empfehlenswert, da hier das Objekt tatsächlich kopiert wird ("Call by Value"). Ja. Einen solchen Konstruktor sollte man auch nicht schreiben, da der Compiler syntaktisch gesehen in allen Fällen wo dieser greift, den 'sparsameren' Copy Constructor benutzen kann.