Klassen, Pointer, Referenzen in C++

  • C++

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von Trade.

    Klassen, Pointer, Referenzen in C++

    Bezug: Seltsames Verhalten einer selbst geschriebenen Klasse - Automatischer Destruktoraufruf

    Ich weiss auch garnicht, ob der Vector ühaupt zu kopieren wäre - ist das nicht eine class, also wassich als Referenztyp kenne? Solch kopiert man doch garnet bei Zuweisungen - jdfs. nicht in c#.


    In eigenen Thread ausgelagert
    -Artentus

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Artentus“ ()

    In C# hast du Klasseninstanzen immer aufm Heap. In C++ im Normalfall aufm Stack. Deswegen müssen die auch nicht freigegeben werden. So eine Klasse hat per Default 3 Konstruktoren, einmal den Standard class(), dann den Kopierkonstruktor class(const class&) und den Movekonstruktor class(const class&&). Der Kopierkonstruktor kopiert einfach alle Felder innerhalb der Klasse, genau wie Operator-=. Hast du ein Objekt aufm Heap und setzt =, dann werden ja die Zeiger gleichgesetzt (sprich class* = class*). Da ist dann der Speicher identisch. Aufm Stack wirds aber Kopiert (oder Heap halt *class = *class). Deswegen übergibst man auch Objekte als const&, damit nicht alles kopiert wird. Hast du als Parameter einen std::string, wird der komplette Speicher kopiert (geht auf Performance und Speicher), bei const std::string& wird die readonly Referenz übergeben.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Artentus“ ()

    @gonger96: das war nicht meine Frage, sondern ob der Vektor ein Referenztyp ist.
    Damit meine ich, wenn man nun die Button->_v1 - Property (ist doch eine, oder?) in einer Variablen v speichern würde, und dann würde man v->X ändern - wäre dann des Buttons Position geändert oder nicht?
    Wenn ja, dann ist Vector ein Ref-Typ in meinem Verständnis, wenn nein, dann ists, was ich als struct kenne.

    hmm, nun sehe ich:

    C-Quellcode

    1. class Vector2D {
    2. //...
    3. int X() const;
    4. int Y() const;
    5. };
    solch const scheint andere Bedeutung zu haben - entspräche das dem c# - readonly - Begriff?
    Also wäre Vector X nicht const, hätte dann die o.g. Änderung den Effekt auf den Button?
    In C++ gibt es keine Properties, das regelt man private und implementiert Methoden, die die Werte zurückgeben/setzen.
    Und nein, das wäre dann nicht geändert, sondern es wird ja nur der Speicher kopiert und ist dann damit nicht mehr verbunden. Geändert wird es nur, wenn Du Referenzen (&) nutzt.

    Und ja, const ist ReadOnly, aber selbst wenn es das nicht ist, wird es nicht geändert (s. o). ;)

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:

    ErfinderDesRades schrieb:

    Damit meine ich, wenn man nun die Button->_v1 - Property (ist doch eine, oder?) in einer Variablen v speichern würde, und dann würde man v->X ändern - wäre dann des Buttons Position geändert oder nicht?

    Nein, die Position des Buttons bleibt gleich. Der Vector wird bei der Zuweisung kopiert. In C++ gibt es keinen Unterschied zwischen struct und class, bis auf dass in struct default alles public ist und in class private. Properties gibts nicht, man hat für gewöhnlich ein privates Feld und dann je nach dem const get_property() und set_property(). So kann man auch schön Templates drin nutzen. Hast du jetzt aber ein new mit drin und einen Vector2D*/Vector2D&, dann hat man das was du Referenztyp nennst.

    ErfinderDesRades schrieb:


    hmm, nun sehe ich:

    C-Quellcode

    1. class Vector2D {
    2. //...
    3. int X() const;
    4. int Y() const;
    5. };
    solch const scheint andere Bedeutung zu haben - entspräche das dem c# - readonly - Begriff?
    Also wäre Vector X nicht const, hätte dann die o.g. Änderung den Effekt auf den Button?


    Soviel Ich weiß sind const hinter Methoden dafür da, dass innerhalb der Methode keine Variablen, auf welche innerhalb der ganzen Klasse zugegriffen werden kann, geändert werden können (also nicht wie in c#)
    Jo, insofern es nicht mutable ist. Aber ihm ging es ja um die Member selber, nicht Methoden. ^^

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    also ich hab nu die Vector2D::X()-Signator wie folgt modifiziert:

    C-Quellcode

    1. void X(int value);
    2. int X() ;
    Und erreiche mit diesem Test den Referenz-Typ-Effekt, also die Änderung von v0.X rückwirkt auf v1.X:

    C-Quellcode

    1. Vector2D v0(22, 99);
    2. Vector2D &v1 = v0;
    3. Vector2D v2 = v0;
    4. int x = v0.X();
    5. v0.X(33);
    6. int x1 = v1.X(); // = 33
    7. int x2 = v2.X(); // = 22
    vielen Dank für diesen kleinen Einblick in die andere Denke, also je wie man ein c++ - Objekt addressiert verhält es sich wie was ich als struct oder class kenne.
    Bisserl Komisch, dass v2.X() ebenso geht wie v1.X(), obwohl v1 doch gar kein Vector ist, sondern ein Vector* - richtig? (Intellisense zeigt es als Vector2D &v1 an)
    Nein, v1 ist eine Referenz, kein Pointer. Pointer wäre es mit Vector2D* und dann die Zuweisung mit new oder Vector2D* v1 = &v0. Beachte das hier dann & der Adressierungsoperator wäre. Wenn es so ein Pointer wäre, ginge das ja mit .X(), wie Du richtig gesagt hast, gar nicht, sondern nur mit -> bzw. (*v1).X().

    Grüße ​​
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Da ist noch ein kleiner Unterschied. v1 ist eine Referenz auf einen Vector2D also ein Vector2D&, ein Zeiger ist etwas anderes nämlich ein Vector2D*

    C-Quellcode

    1. Vector2D v0(22, 99);
    2. Vector2D* v1 = &v0;
    3. v0.X(33);
    4. int x1 = v1->X(); // = 33

    Verhält sich aber genauso. Man verwendet Zeiger aber eigentlich nur zur Polymorphie und als Iterator. Gibt etliche verschiedene Modifikationen von Vector2D: Vector2D*, Vector2D**, Vector2D&, Vector2D&& etc. Das ganze natürlich noch in Kombi mit const, volatile, mutable usw.
    Genau. Zeiger verwendest Du, wie Gonger gesagt hat, nur für Polymorphie und Iteratoren. Ansonsten haben sie in C++ nicht mehr so die Bedeutung wie in C.

    Polymorphie halt, damit Du das dann so regeln kannst, wie zum Beispiel der TE hier das macht (erbt von komponente). Iteratoren, weil Du da einen Pointer auf einen Typen erstellst (z. B. char*) und dann somit mit einem gewissen Count jedes Mal die Adresse des Pointers inkrementiert werden kann, um weitere Chars auszulesen und zum Beispiel dann als String zusammenzufügen. Deswegen ist ein String ja auch nichts anderes, als auf einem char* aufbauend. Gut, das ist jetzt kein ganz so perfektes Beispiel, da es ja schon std::string fertig etc. gibt und das normal auch über '\0' läuft, also bis das nullterminiert ist, aber gut.^^

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!: