Const und Properties



  • ich habe eine vector klasse mit einer property

    property float X {
        float get(void) { return vector[_X]; }
        void set(float value) { vector[_X] = value; }
    }
    

    und übergebe eine objektreferenz an eine methode einer matrix klasse

    PinkballsOpenGL::Math::Matrix PinkballsOpenGL::Math::Matrix::Translation(const Vector3 %aTranslation)
    {
    	return Translation(aTranslation.X, aTranslation.Y, aTranslation.Z);
    }
    

    dabei bekomme ich den folgenden compiler error:

    error C2662: 'PinkballsOpenGL::Math::Vector3::X::get' : cannot convert 'this' pointer from 'const PinkballsOpenGL::Math::Vector3' to 'PinkballsOpenGL::Math::Vector3 %'
    

    in native c++ ist das deswegen weil die get methode nicht als const geflagged ist und deswegen ein const objekt sie nicht ausführen darf, nur methoden mit const keyword versehen die garantieren dass das objekt in ihnen nicht verändert wird dürfen von einer const referenz ausgeführt werden soweit ich bescheid weiss

    allerdings darf man in c++ das const keyword für methoden nicht verwenden

    also, es ist nicht erlaubt zu schreiben

    property float X {
        float get(void) [b]const[/b] { return vector[_X]; }
        void set(float value) { vector[_X] = value; }
    }
    

    denn das liefert den folgenden error

    error C3842: 'get': 'const' and 'volatile' qualifiers on member functions of managed types are not supported

    also, was muss man in c++/cli machen wenn man konstante zugriffsmethoden braucht?



  • const für Member Methoden in C++/CLI sind nicht unterstützt.



  • "static" ?



  • Vevusio schrieb:

    allerdings darf man in c++ das const keyword für methoden nicht verwenden

    also, es ist nicht erlaubt zu schreiben

    property float X {
        float get(void) [b]const[/b] { return vector[_X]; }
        void set(float value) { vector[_X] = value; }
    }
    

    simon.gysi schrieb:

    const für Member Methoden in C++/CLI sind nicht unterstützt.

    oh wow simon danke, es ist nicht so als wenn ich das nicht selbst sogar hingeschrieben hätte -.-

    Jochen Kalmbach schrieb:

    "static" ?

    wenn die properties static sind könnten sie ja nicht auf die member von der klasse zugreifen, außer die wären auch static, aber mehr als ein einziges set an xyz koordinaten zu haben wäre schon ganz nett *g*

    im moment manche ich es so

    PinkballsOpenGL::Math::Matrix PinkballsOpenGL::Math::Matrix::Scaling(const Vector3 %aScaling)
    {
    	Vector3 temp(aScaling);
    	return Scaling(temp.X, temp.Y, temp.Z);
    }
    

    aber das ist mehr ein hack als ne lösung



  • PinkballsOpenGL::Math::Matrix PinkballsOpenGL::Math::Matrix::Translation(const Vector3 %aTranslation)
    {
        return Translation(aTranslation.X, aTranslation.Y, aTranslation.Z);
    }
    

    Ist PinkballsOpenGL::Math::Matrix::Translation eine managed Funktion und Translation eine native Funktion? Verstehe ich das korrekt?

    Ich verstehe nicht ganz das Problem:
    Entweder ist PinkballsOpenGL::Math::Matrix ein native Type oder es sollte PinkballsOpenGL::Math::Matrix^ als Rückgabewert heissen, oder?

    Edit:
    Warum übergibst Du (const Vector3 %aTranslation) nicht so: (const Vector3^ aTranslation)??



  • nein Translation ist keine native funktion, beide PinkballsOpenGL::Math::Matrix::Translation methoden sind member einer managed matrix klasse, die methode

    PinkballsOpenGL::Math::Matrix PinkballsOpenGL::Math::Matrix::Translation(const Vector3 %aTranslation)
    {
        return Translation(aTranslation.X, aTranslation.Y, aTranslation.Z);
    }
    

    ruft lediglich einen overload auf und zwar

    PinkballsOpenGL::Math::Matrix PinkballsOpenGL::Math::Matrix::Translation(float aX, float aY, float aZ)
    {
    	float *matrix = new float[FIELDS];
    
    	//  | 1  0  0  X |
    	//M=| 0  1  0  Y |
    	//  | 0  0  1  Z |
    	//  | 0  0  0  1 |
    	matrix[_11] = 1; matrix[_21] = 0; matrix[_31] = 0; matrix[_41] = aX;
    	matrix[_12] = 0; matrix[_22] = 1; matrix[_32] = 0; matrix[_42] = aY;
    	matrix[_13] = 0; matrix[_23] = 0; matrix[_33] = 1; matrix[_43] = aZ;
    	matrix[_14] = 0; matrix[_24] = 0; matrix[_34] = 0; matrix[_44] = 1;
    
    	return Matrix(matrix);
    }
    

    PinkballsOpenGL::Math::Matrix ist ebenfalls ein managed typ

    public ref class Matrix sealed
    

    es sollte PinkballsOpenGL::Math::Matrix^ als Rückgabewert heissen, oder?

    jain... normalerweise schon aber es werden viele matrizen erstellt und ich möchte dass sobald sie den scope verlassen automatisch gelöscht werden, ich verwende keine

    Matrix ^matrix = gcnew Matrix();
    

    sondern erstelle sie eigentlich immer mit

    Matrix matrix;
    

    damit sie eben nicht vom garbage collector aufgegabelt werden müssen bzw man nicht immer am ende jeder methode über delete jede einzelne matrix freigeben muss die man erstellt hat

    direkt

    PinkballsOpenGL::Math::Matrix
    

    zurückzugeben und nicht

    PinkballsOpenGL::Math::Matrix ^
    

    ist auch kein problem, man muss nur den copy construktor definieren

    Matrix(const Matrix %aMatrix);
    

    Warum übergibst Du (const Vector3 %aTranslation) nicht so: (const Vector3^ aTranslation)

    für vektoren gilt dasselbe wie für matrizen, ich will nicht den garbage collector das machen lassen bzw dauernd delete aufrufen müssen

    da ich also praktishc nur vektoren erstelle über

    Vector3 vector(x,y,z);
    

    nehmen die methoden referenzen auf die vektoren, wenn es pointer wären müsste ich jeden vektor erst referenzieren zb

    Vector3 normalized = Vector3::Normalize(&vector);
    

    (so würde es aussehen wenn Normalize als parameter einen const Vector3 ^aVectorToNormalize als parameter bekommen würde)

    aber über ne referenz kann ich einfach schreiben

    Vector3 normalized = Vector3::Normalize(vector);
    

    (so würde es aussehen wenn Normalize als parameter einen const Vector3 %aVectorToNormalize als parameter bekommen würde)

    aber selbst wenn ich

    const Vector3 ^aVector

    übergeben würde, wäre es immer noch dasselbe problem mit dem zugriff



  • Warum machts Du die Typen nicht "value class", die Du nicht mit gcnew erzeugen möchtest?



  • weil die open gl matrix operationen einen float * erwarten der auf 16 floats zeigt für eine 4x4 matrix

    ich kann in einer managed klasse kein

    float matrix[16]
    

    als member erstellen weil das ein unmanaged typ ist also geht nur

    float *matrix;
    

    und später im konstruktor

    matrix = new float[16];
    

    also ist ein default konstruktor naheliegend um nicht in jeder methode checken zu müssen

    if(matrix == NULL)
        matrix = new float[16]
    

    und das braucht schonmal eine managed class, ausserdem brauche ich einen finalizer zusätzlich zu dem destruktor (soweit ich das verstanden habe ruft der GC den destructor auf und delete bzw local scope termination den finalizer)

    ~Matrix(void); //destructor
    !Matrix(void); //finalizer
    

    und finalizer sind auch nur in einer managed klasse vorhanden und nicht in value class

    ka ob ne value class überhaupt einen destructor haben kann? habs nie probiert

    und ich würde immer noch gerne wissen wie in C++/CLI das const keyword für methoden ersetzt wird damit man auf const pointer und const references methoden zugreifen kann



  • Sorry, dass ich immer wieder frage, aber warum nimmst Du float* und nicht ein managed float array?

    Ehrlich gesagt, ich habe das urspüngliche Problem noch gar nicht verstanden.



  • weil open gl das hier will:

    void glMultMatrixf(const GFloat *m);

    openGL ist unmanaged, ich kann es nicht mit managed arrays füttern, deswegen speicher ich direkt unmanaged arrays ab die ich opengl direkt übergeben kann

    ich speichere nicht ein array<float> weil ich dann jedesmal wenn ich für opengl die matrix auspacken müsste das zu einem float * array konvertieren müsste und nachher wieder das float * array deleten müsste

    das problem ist folgendes

    ref class Mini
    {
        private:
            int x;
        public:
            void GetX()
            {
                return x;
            } 
    }
    

    und irgend eine methode egal wo

    void PrintMinisX(const Mini % mini)
    {
        System::Console::WriteLine( "Mini's x is " + mini.GetX() );
    }
    

    geht in c++/cli nicht, in c++ würde man einfach die get methode schreiben als

    void GetX() [b]const[/b] //<-- durch dieses const ist die methode selbst "const" und darf auch von const pointern und referenzen aufgerufen werden
    {
        return x;
    }
    

    aber in C++/CLI gibt es const für methoden nicht mehr, baaam



  • void PrintMinisX(Mini % mini)
    {
        System::Console::WriteLine( "Mini's x is " + mini.GetX() );
    }
    

    Würde so gehen, oder?



  • ja


Anmelden zum Antworten