const* als Rückgabewert funktioniert nicht ?



  • Hi 🙂 , habe nur ne kurze Verständnisfrage zu const*.

    Folgendes Beispiel habe ich mir zum verstehen gebaut und das klappt alles so, wie ich es verstehe:

    #include <stdio.h>
    
    class A
    {
    public:
    	A() {x=10;}
    	int getX(){return x;}
    
    private:
    	int x;
    };
    
    void main()
    {
    	A * const ptr1 = new A();
    	ptr1->getX();                 //Geht
    	//ptr1 = NULL;                //Geht nicht, weil Pointer konstant ist
    
    	const A * ptr2 = new A();     
    	//ptr2->getX();                //Geht nicht, weil könnte verändern werden
    	ptr2 = NULL;                   //Geht
    
    	const A * const ptr3 = new A(); 
    	//ptr3->getX();                //Geht nicht, weil könnte verändern werden
    	//ptr3 = NULL;                 //Geht nicht, weil Pointer konstant ist                  
    }
    

    Nun habe ich mir ein 2. gebastelt, aber das funzt net..und verstehe nicht warum.
    Kann doch bei einem const Pointer (Wie obiges Beispiel) den Inhalt auf den gezeigt wird, beliebig verändern. Kann ja nur nicht den Inhalt des Pointers selber verändern. Warum klappts denn in meinem 2. Beispiel net ? 😕

    #include <stdio.h>
    
    class A
    {
    public:
    	A() {x=10;}
    	int getX(){return x;}
    
    private:
    	int x;
    };
    
    class B
    {
    public:
    	B(){back = new A();}
    
    	A const * getBack() {return (A const*) back;}
    private:
    	A * back;
    };
    
    void main()
    {
    	B * b = new B();
    
    	b->getBack();         //Das geht
    
    	b->getBack()->getX(); //CompilerFehler: Warum ? Ist doch nur konstanter Pointer ?
    }
    

    Folgende Compilerfehlermeldung bekomme ich immer:

    error C2662: 'getX' : this-Zeiger kann nicht von 'const class A' in 'class A &' konvertiert werden. Durch die Konvertierung gehen Qualifizierer verloren

    (VC6.0++)

    Vielleicht wisst Ihr da, warum das net funzt.

    MFG

    FinalbrainXP



  • A const * getBack()
    

    Denk nochmal darüber nach, was das zurück liefert.



  • Mach aus dem hier:

    int getX(){return x;}
    

    das hier:

    int getX() const {return x;}
    


  • (Bezug Auf Optimizers Antwort)

    Achso..habe es verändert...jetzt gehts Danke!

    A * const getBack() {return (A * const) back;}

    Es gibt also 3 Möglichkeiten ? 😮

    1.) A * const ptr;
    2.) const A * ptr;
    3.) A const * ptr; //Dasselbe wie 2. ?

    Vielen Dank 😉

    Gruss

    Finalbrain



  • FinalbrainXP schrieb:

    (Bezug Auf Optimizers Antwort)

    Achso..habe es verändert...jetzt gehts Danke!

    A * const getBack() {return (A * const) back;}

    Ist das const hier nicht völlig sinnlos?

    Es gibt also 3 Möglichkeiten ? 😮

    1.) A * const ptr;
    2.) const A * ptr;
    3.) A const * ptr; //Dasselbe wie 2. ?

    Ja



  • 2 und 3 sind äquivalent. Statt dem Cast, solltest du die Methode überladen:

    A& foo() { return a; }
    const A& foo() const { return a; }
    

    In deinem Fall reicht aber eine const-Methode, weil du sowieso eine Kopie des Zeigers zurückgibst.



  • @Interpreter

    Danke für deinen Tipp ebenfalls...aber hatte was anderes gemeint:
    Wollte einen const Pointer auf class A. nicht umgekehrt. 😉
    Wird jetzt in meine Engine gebaut..aber davon sage ich nichts mehr 😃

    Gruss

    Finalbrain



  • FinalbrainXP schrieb:

    @Interpreter
    Wollte einen const Pointer auf class A. nicht umgekehrt. 😉

    Der dir aber nichts bringt, weil das eh kein L-Value ist.



  • Ach ja..habe gleich noch ne Frage dazu...

    Interpreter hat völlig recht damit, das es völlig unnütz ist.
    Kann mir jemand denn in nen paar setzten erklären, warum man in c++ nicht on the fly zuweisungen machen kann ? (Oder wie man das nennt)

    Weil wollte mich ja mit dem const Ponter absichern, das
    man nicht folgendes machen kann.

    B * b = new B();
    b->getBack()=NULL;

    ..aber dieses on the Fly setzen geht ja eh nicht irgendwie..weiss jemand warum ?

    Gruss

    Finalbrain



  • FinalbrainXP schrieb:

    Ach ja..habe gleich noch ne Frage dazu...

    Interpreter hat völlig recht damit, das es völlig unnütz ist.
    Kann mir jemand denn in nen paar setzten erklären, warum man in c++ nicht on the fly zuweisungen machen kann ? (Oder wie man das nennt)

    Weil wollte mich ja mit dem const Ponter absichern, das
    man nicht folgendes machen kann.

    B * b = new B();
    b->getBack()=NULL;

    ..aber dieses on the Fly setzen geht ja eh nicht irgendwie..weiss jemand warum ?

    Gruss

    Finalbrain

    Wie gesagt, weil das kein L-Value ist. Wenn du dem Rückgabewert "on the fly 😃 " etwas zuweisen willst, dann musst du eine Referenz zurückgeben.
    z.B.:

    A *& getBack()  { return back; }
    


  • Das hieße also, ich müsste dem ne Referenz auf nen A-Pointer zurückgeben ?

    Und ne Referenz ist doch nen dereferenzierter Pointer in dem Sinne ?
    (Hasse Referenzen, weil ich von C komme 😃 )

    Also geht so:

    #include <stdio.h>
    
    class A
    {
    public:
    	A() {x=10;}
    	int getX(){return x;}
    
    private:
    	int x;
    };
    
    class B
    {
    public:
    	B(){back = new A();}
    
    	A ** getBack() {return  &back;}
    private:
    	A * back;
    };
    
    void main()
    {
    	B * b = new B();
    
    	(*(b->getBack()))=NULL;
    
    }
    

    ..glaube habe es verstanden. Erst durch das dereferenzieren bekomme ich ein L-Value, da ich ja vorher nur nen einfachen Pointer hatte.



  • FinalbrainXP schrieb:

    Das hieße also, ich müsste dem ne Referenz auf nen A-Pointer zurückgeben ?

    Japp.

    Und ne Referenz ist doch nen dereferenzierter Pointer in dem Sinne ?

    So wird es wohl meistens implementiert werden, ja.

    Also geht so:

    #include <stdio.h>
    
    class A
    {
    public:
    	A() {x=10;}
    	int getX(){return x;}
    
    private:
    	int x;
    };
    
    class B
    {
    public:
    	B(){back = new A();}
    
    	A ** getBack() {return  &back;}
    private:
    	A * back;
    };
    
    void main()
    {
    	B * b = new B();
    
    	(*(b->getBack()))=NULL;
    	
    }
    

    ..glaube habe es verstanden. Erst durch das dereferenzieren bekomme ich ein L-Value, da ich ja vorher nur nen einfachen Pointer hatte.

    Ja, das sollte gehen. Ich hoffe, dass du das nur zu Lern/Testzwecken schreibst und nicht wirklich verwenden willst. 😉



  • @Interpreter..gibt es in c++ auch so schöne Tricks wie in c ? Du kennst doch da bestimmt welche 😉

    Beispiel:

    int a[9][9];
    1[1[a]] = 666; // <=> a[1][1] = 666;
    

    Ps: Sind nur Lernzwecke 😃 😃 (Auch nen Nachtmensch was ? 🤡 )



  • muß das nicht eher 1[&1[a]] heißen?



  • Hmm...also habe es mit & getestet..da geht es nicht, weil

    int a[10][10];

    a[9][9] <=>
    ((a+9)+9) <=>
    (9+(a+9)) <=>
    (9+(9+a)) <=>
    *(9+9[a]) <=>
    9[9[a]]

    ...und 9[a] ist ja ein dereferenzierter Wert der auf '9'
    draufaddiert wird und das ganze dann wieder derefernziert wird.
    Würde & benutzt, würde ja die Adresse auf 9 addiert werden, und das ganze dann im Nirvana landen. Oder habe ich was falsch verstanden ? 🙂

    Gruss

    Finalbrain



  • schöner beweis.
    du hast recht.



  • FinalbrainXP schrieb:

    @Interpreter..gibt es in c++ auch so schöne Tricks wie in c ? Du kennst doch da bestimmt welche 😉

    Naja, bin bestimmt kein C l337 haxx0r. Aber ganz nett finde ich das:

    int f(int i) { return i; }
    
    int main() {
       int a[] = {1,2,3,4,5,6};
       cout << (f(1[a])[a]);
    }
    

    Sinnlos, aber nett anzusehen 😉
    Beispiel:

    Ps: Sind nur Lernzwecke 😃 😃 (Auch nen Nachtmensch was ? 🤡 )

    Ja 🙄


Anmelden zum Antworten