:: -> oder . - was jetzt?





  • msdiego2k schrieb:

    danke .. auch wenn ich das schwachsinnig finde, java c# php5 üerall reicht der Punkt und hier müssen es 3 Zeichen sein ...

    Aber ich hab noch eine Frage und zwar zur typen umwandlung, das ganze scheint auch nicht einheitlich zu sein:
    const_cast wandelt man const und volatitle um
    static_cast nehm ich bei normalen umwandlungen int nach double nach float usw
    reinterpret_cast wenn man zeiger in Zahlen und umgekehrt umwandeln will?

    Wenn es dir nicht passt, kannst du ja wieder zu Java, C# oder PHP zurück. Zwingt dich ja niemand.. Im übrigen hat es seine Gründe, warum es so "viele" Zeichen gibt. Sie haben unterschiedliche Bedeutungen und bezwecken andere Sachen. Diese Möglichkeiten hast du in anderen Sprachen nicht.

    reinterpret_cast ist dazu da, um alles andere zu casten, was die anderen 2 nicht können (wenn es nötig ist). Und sollte dementsprechend selten anzutreffen sein. Er wandelt überhaupt nichts um, sondern belässt das Bit Muster genau so und ist manchmal nötig, wenn man mit etwas älteren API's arbeitet, die z.B einen Zeiger, unbekannten Types speichern wollen.



  • msdiego2k schrieb:

    danke .. auch wenn ich das schwachsinnig finde, java c# php5 üerall reicht der Punkt und hier müssen es 3 Zeichen sein ...

    Das liegt an den C-Wurzeln von C++. Du kannst alles mit Referenzen machen, dann baruchst Du weder * noch ->



  • Das liegt an den C-Wurzeln von C++. Du kannst alles mit Referenzen machen, dann baruchst Du weder * noch ->

    das hier dürfte dir weiter helfen.............Operator &

    ➡ http://tutorial.schornboeck.net/referenzen.htm :xmas1:



  • c++fan 2008 schrieb:

    msdiego2k schrieb:

    danke .. auch wenn ich das schwachsinnig finde, java c# php5 üerall reicht der Punkt und hier müssen es 3 Zeichen sein ...

    Das liegt an den C-Wurzeln von C++. Du kannst alles mit Referenzen machen, dann baruchst Du weder * noch ->

    Alles nicht. Zeicher haben auch jetzt noch ihre Gründe.
    Nichtsdestotrotz kann man für viele Aufgaben, für die Zeiger verantwortlich waren Heute auch Referenzen benutzen.



  • erstmal danke für die antworten, weiß jetzt das was ich wissen wollte.

    Und nicht gleich beleidigt sein wenn ich was als Schwachsinn bezeichne 🙄 is ja nicht so gemeint

    Das mit den refs find ich super, ^^

    Nur das man ein neues Objekt sowie die Instanz einer Klasse so erstellt
    Klasse obj;
    find ich komisch, das sieht ja so aus als wäre hier nur mal das Objekt erstellt worden und man müsste erst die instanz erstellen;
    obj = new klass();
    also klasse obj = new klasse();

    aber das is ja falsch, das geht hier wieder nur wenn man zuerst nen Zeiger erstellt
    klasse* obj;
    obj = new klasse();
    und dann brauch ich wieder den komischen ->
    obj->meth(asd);



  • Casts sind generell selten anzutreffen, am häufigsten ist wohl static_cast . const_cast sollte man möglichst überall vermeiden. dynamic_cast lässt sich oft durch kleine Designänderungen (virtuelle Funktionen) ersetzen, und reinterpret_cast ist eigentlich nur bei Low-Level-Operationen nötig, oder wenn man beispielsweise mit C-APIs programmiert.

    Das Schlimmste ist aber der Klammer-C-Cast-Operator, denn der ist böse und versucht, die Typen irgendwie umzubiegen. In C++ sollte man wenn möglich die spezialisierten Cast-Operatoren verwenden.

    Zu deinem Problem: Du musst grundsätzlich zwischen Zeigern und Objekten unterscheiden, vielleicht solltest du das nochmals nachlesen. Im Übrigen ist Objekt das Gleiche wie Instanz.

    Klasse obj;                 // erstellt ein Objekt der Klasse. Das existiert nun schon, new ist unnötig.
    Klasse* ptr = new Klasse(); // Legt einen Zeiger an, dem gerade ein Speicherbereich zugesichert wird.
                                // Eine Instanz wurde mit new auch gerade konstruiert.
    delete ptr;              // Zerstört die Instanz und gibt den Speicher frei.
    

    Edit: Flüchtigkeitsfehler ( delete Klasse; )



  • Welche art der Konvertierung gibt’s denn noch?
    Im Buch ist nur gestanden ich soll die c-casts lassen, also das (char …), und die neuen Typenumwandlungs Operatoren verwenden:
    Const static dynamic reinterpret, bei mir hat der static eigentlich immer funktioniert bis auf die strings da geht’s mit den stringstream recht gut.
    Obwohl es funktioniert auch das:
    Char asd=’f’;
    Int k = asd;
    o.O

    Das mit den Zeigern werd ich mir glaub ich noch mal anschauen, is ja ne dubiose Geschichte, aber bin sowieso noch lange nicht fertig ..

    Objekt ist so was wie ein Model, erst wennst es instanzierst hauchst ihm leben ein.
    Jede instanz is ein Objekt umgekehrt muss das aber nicht sein

    Class1[] asd = new Class1[3];
    asd[1] = new Class1();// würdest die Zeile weglassen gibts nen Fehler weil noch keine instanz aufm objekt ist
    asd[1].funkt();



  • Das ist eben bei C++ anderst, als z.B in C#. Wenn du einen Typen in einer Funktion deklarierst:

    Class instance;
    

    Dann wird bereits ein Objekt erstellt und der Standardkonstruktor aufgerufen. (Es ist also auch eine Definition) Hier hast du ein Objekt, dass lediglich im deklarierenden Scope lebt und danach (bei dem } ) wieder zerstört wird (automatisch). In einer Klasse lebt das Objekt so lange, wie die Klasse selbst lebt. Wobei die Initialisierung noch vor dem Konstruktor stattfindet. (in der Initialisierungsliste, gibt es in C# z.B auch nicht).

    Auf ein solches Objekt kannst du auch per .-Operator zugreifen. (oder, wenn einer definiert ist einen -> Operator, den du nämlich selber überladen kannst).

    Wenn du allerdings einen Zeiger auf ein Objekt erstellst:

    Class* pinstance;
    

    Dann ist das lediglich die deklaration eines Zeigers (und somit auch Definition). Aber du hast noch kein Objekt vom Typen Class, sondern erst einen Zeiger darauf. Also musst du jetzt noch an den Speicher kommen. Dazu gibt es 2 "Techniken":
    1. Du benutzt den Zeiger lediglich als Verweis auf ein Objekt, dass automatisch verwaltet wird:

    Class instance;
    Class* pinstance = &instance;
    

    Hier ist pinstance solange gültig, wie auch instance gültig ist. (Solange sich beide im selben Scope befinden, ist das kein Problem, da der Zeiger selbt dann auch zerstört wird. Wenn nicht, ist vorsichtig damit umzugehen, da der Zeiger auf ungültigen Speicher zeigen kann. Das ist der Grund, warum das hier böse ist:

    int* GetInteger ()
    {
     int i;
     return &i;
    }
    

    Der zurückgegeben Zeiger wird nie auf gültigen Speicher zeigen und jegliches operieren damit ist undefiniert.

    2. Du holst dir den Speicher vom Freispeicher und verwaltest alles selbst

    Class* pinstance = new Class();
    

    pinstance lebt hier solange, wie du nicht delete auf pinstance aufrufst. Somit ist auch hier vorsicht geboten, da nicht vergessen werden darf den Speicher wieder richtig freizugeben. Somit ist das hier auf eine Weise auch böse:

    int* GetInteger ()
    {
     return new int;
    }
    

    Da der Aufrufer, wenn er es nicht weiss, dass er den Speicher freigeben soll es auch kaum tun wird. Allerdings wird diese Technik auf verschiedene Arten noch benutzt, indem z.B eine Klasse sich um die Speicherverwaltung kümmert, oder dir explizit vorgegeben wird, dass du den Speicher wieder freigeben musst. (z.B COM).

    Wie du siehst, ist das ganze ein wenig anderst, als in anderen Sprachen. Und das hat Vor und Nachteile. Wichtig ist nur, dass du dir bewusst bist, dass du in C++ vorsichtiger mit new umgehen musst und es nicht im selben Sinne, wie in anderen Sprachen benutzt wird. (Vor allem, dass du den Speicher auch wieder freigeben musst ist speziell).
    Jetzt sollte dir aber auch langsam klar werden, wo die Unterschiedlichen Aspekte von Zeigern auf Objekte und normalen Objekte liegt.

    So, ich hoffe, ich konnte ein wenig Licht ins Dunkle bringen. 🙂
    Ein gutes C++ für Umsteiger, der die (manchmal doch entscheidenden) Unterschiede der Sprache aufzeigt, auch wenn sie manchmal gar nicht anderst aussehen. (alleine schon so etwas einfaches, wie if hält in C++ einige Überraschungen für Leute, die von C#/Java kommen :))



  • Im Buch ist nur gestanden ich soll die c-casts lassen, also das (char …), und die neuen Typenumwandlungs Operatoren verwenden:
    Const static dynamic reinterpret, bei mir hat der static eigentlich immer funktioniert bis auf die strings da geht’s mit den stringstream recht gut.
    Obwohl es funktioniert auch das:
    Char asd=’f’;
    Int k = asd;

    Die 3 genannten und C-Casts.

    Das dort geht, weil chars intern auch Zahlenwerte haben, die sich umwandlen lassen.

    Wegen der anderen Frage siehe einen Post weiter oben. 😉



  • danke für die mühe ^^



  • Nexus schrieb:

    Klasse obj;                 // erstellt ein Objekt der Klasse. Das existiert nun schon, new ist unnötig.
    Klasse* ptr = new Klasse(); // Legt einen Zeiger an, dem gerade ein Speicherbereich zugesichert wird.
                                // Eine Instanz wurde mit new auch gerade konstruiert.
    delete Klasse;              // Zerstört die Instanz und gibt den Speicher frei.
    

    es müsste

    delete ptr;
    

    heißen



  • Stimmt natürlich, kleiner Flüchtigkeitsfehler. Ich werde es oben editieren.


Anmelden zum Antworten