Zu Blöde um Objekt zu erzeugen und auf pub Variable zuzugreifen.



  • Hallu Forum

    Ursprünglich gehöre ich eigentlich der Java Fraktion an, aus verschiedensten Gründen möchte ich aber jetzt ein Projekt mit Microsoft Visual C++
    2005 realisieren. Das Objektmodell von C++ ist mir eigentlich auch bekannt, aber ich schaffe es nicht unter Visual C++ eine Klasse zu schreiben
    und anschließend von dieser ein Objekt zu erzeugen, um u.A. auf die Globalen variablen des Objektes zuzugreifen

    Aufruf:
    rr r = new rr();

    rr.h

    #pragma once

    class rr
    {
    public:
    rr(void);
    public:
    ~rr(void);
    };

    "error C2440: 'Initialisierung': 'rr *' kann nicht in 'rr' konvertiert werden
    Quelltyp konnte von keinem Konstruktor angenommen werden, oder die Überladungsauflösung des Konstruktors ist mehrdeutig"

    --> Was in Gottes Namen ist denn überhaubt so ein Stern Objekt?



  • string[34] schrieb:

    --> Was in Gottes Namen ist denn überhaubt so ein Stern Objekt?

    Ein Zeiger.



  • Wenn du ja anscheinend Wissen hast was Visual C++ angeht wirst du mir doch sicher sagen können wie man jetzt auf eine Variable des Objektes zugreift?

    Ich weiß das in dem beispiel von mir keine drinnen ist, aber auch wenn eine unter Public definiert währe kommt trotzdem eine Fehlermeldung.



  • Dieser Thread wurde von Moderator/in Jochen Kalmbach aus dem Forum C++/CLI mit .NET in das Forum C++ (auch C++0x und C++11) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Als Javaumsteiger gilt erstmal die Regel "new ist böse". Niemals verwenden. In Java ist new nötig, in C++ nicht.

    Jetzt zu deinem Problem:

    struct rr{ //struct um den public:-Kram nicht zu brauchen
        //Konstruktoren und Destruktoren baut dir der Compiler automatisch
        int variable;
    };
    
    int main(){
        rr r; //das baut dir ein Objekt r vom Typ rr (Keine Referenz, daher kein new)
        r.variable = 5;
    }
    


  • aus verschiedensten Gründen möchte ich aber jetzt ein Projekt mit Microsoft Visual C++ 2005 realisieren.

    Ich hoffe, es ist einer dabei der die Version rechtfertigt...

    Das Objektmodell von C++ ist mir eigentlich auch bekannt, aber ich schaffe es nicht unter Visual C++ eine Klasse zu schreiben und anschließend von dieser ein Objekt zu erzeugen

    Widerspruch.

    auf die Globalen variablen des Objektes zuzugreifen

    Ein Objekt hat keine globalen Variablen. Du bringst die Begriffe durcheinander.

    Ursprünglich gehöre ich eigentlich der Java Fraktion an

    In C++ erzeugt man Objekte standardmäßig auf dem Stack, wo es aber aus verschiedenen Gründen nötig ist auch auf dem Heap ( new / delete , bzw. make_shared und Konsorten).
    Ein Objekt mit automatic storage duration, wie man es nennt, wird erzeugt sobald das Statement mit seiner Deklaration* im logischen Programmablauf durchlaufen wird.

    std::string str{"ABC"}; // direct-list-initialization. Objekt str vom Typ std::string wird erzeugt.
    


  • ...



  • Sone schrieb:

    In C++ erzeugt man Objekte standardmäßig auf dem Stack, wo es aber aus verschiedenen Gründen nötig ist auch auf dem Heap (new/delete, bzw. make_shared und Konsorten).
    Ein Objekt mit automatic storage duration, wie man es nennt, wird erzeugt sobald das Statement mit seiner Deklaration* im logischen Programmablauf durchlaufen wird.

    std::string str{"ABC"}; // direct-list-initialization. Objekt str vom Typ std::string wird erzeugt.
    

    Es ist prinzipiell gut, dass du auf den neuen Standard setzt, aber an Visual C++ 2005 wird der TE kein C++11 vorbeibekommen. Der kann nicht mal TR1.

    Ansonsten hatte ich vor einer Weile die grundlegenden Unterschiede zwischen den Objektmodellen in C++ und Java zusammenzufassen versucht; das Posting befindet sich hier. Vielleicht hilft es ja beim Verständnis. Beachte: Ich beziehe mich da teilweise auch auf C++11-Features (std::unique_ptr und std::shared_ptr), die VC++2005 nicht beherrscht. Ggf. muss auf std::auto_ptr ausgewichen werden, und in Boost findet sich eine shared_ptr-Implementation, die auch mit alten Compilern funktioniert.



  • Es ist mir klar - aber trotzdem egal. Der TE soll nun mal aktuelles C++ lernen, und nicht dabei von seinem Compiler aufgehalten werden. Vor allem regt es ihn dadurch an, sich eine aktuellere Version zu holen - als Hobby Programmierer ist das doch ein leichtes Stück... 😕



  • string[34] schrieb:

    Wenn du ja anscheinend Wissen hast was Visual C++ angeht wirst du mir doch sicher sagen können wie man jetzt auf eine Variable des Objektes zugreift?

    Mit dem . Operator.

    Was muss ich tun um dich davon zu überzeugen, dass du mit Java-Kenntnissen nicht automatisch C++ kannst? Du wirst die Sprache lernen müssen wie jeder andere auch.



  • string[34] schrieb:

    Ursprünglich gehöre ich eigentlich der Java Fraktion an, aus verschiedensten Gründen möchte ich aber jetzt ein Projekt mit Microsoft Visual C++
    2005 realisieren. Das Objektmodell von C++ ist mir eigentlich auch bekannt,

    Aufruf:
    rr r = new rr();

    Ist doch klar, dass das so nicht geht. C++ und Java sind unterschiedlliche Programmiersprachen. Vergiss am besten all den "OOP-Kram", den du aus Java kennst.

    Ein wichtiger Unterschied ist, dass Java einem eine Indirektion für Klassentypen aufzwingt:

    int i = 23;              // i speichert 23 direkt
    int j = i;               // j ist eine zweite int-Variable, die hier mit
                             // dem Wert von i initialisiert wird
    i = 42;                  // j ist danach immer noch 23.
    
    Object o = new Object(); // o speichert nur eine "Referenz" auf ein im
                             // "dynamischen Speicher" liegendes Objekt
    Object p = o;            // Referenz p zeigt jetzt auf dasselbe Objekt wie o
    

    Du hast also in Java ganz automatisch mit Zeigern zu tun. Die nennst du nur "Referenzen".

    In C++ bekommst du nur Zeiger, wenn du explizit danach fragst. Und man kann in C++ Objekte, wie auch ganz "normale Variablen" direkt halten:

    std::string foo = "world"; // ein string-Objekt mit Namen foo
    std::string bar = foo;     // ein komplett anderes string-Objekt mit Namen bar
    foo = "hello";
    cout << foo << ' ' << bar << endl; // gibt "hello world" aus
    

    Genauso, wie du int-Variablen neue Werte zuweisen kann, kannst du einem string-Objekt neue Werte zuweisen. Hier gibt es nirgens "Referenzen" oder "Zeiger". Und genauso wenig, wie du oben für i und j kein new verwendet hast, brauchst du new in diesem Fall auch nicht. foo und bar sind hier zwei verschiedene String-Objekte, die im "automatischen Speicher" leben. Die Variablen/Objekte, die im "automatischen Speicher" liegen, werden automatisch sofort entfernt, wenn die Ausführung den Gültigkeitsbereich verlässt. die string-Klasse verwendet zwar intern dynamisch reservierten Speicher für die Zeichenkette, aber den kann sie auch ordnungsgemäß wieder freigeben. Das ist in C++ möglich, weil ein Klassenautor selbst festlegen kann, was passieren soll, wenn ein Objekt der Klasse kopiert, zugewiesen oder zerstört werden soll. Das ist mit das genialste Feature von C++ überhaupt.

    Als von-Java-nach-C++-Umsteiger wirst du geneigt sein, viele Objekte per new anzulegen und auch als Datenelemente viele Zeiger zu verwenden, weil du es nicht anders kennst. In den meisten Fällen wird das jedoch eine sehr blöde Idee sein. Beispiel:

    class Person
    {
    public:
      explicit Person(const char* n)
      {
        name = new string(n); // new legt ein OBjekt im Freispeicher an und
                              // gibt eine Adresse dafür zurück, welche sich
                              // in einer Zeiger-Variablen speichern lässt.
      }
    private:
      string* name; // Zeiger auf ein string-Objekt
    };
    

    Das ist nicht nur ungeschickt, sondern führt auch zu Speicherlecks, weil zu jedem new irgendwo ein delete gehört. Das Einfügen eines Destruktors, in dem der String gelöscht wird, reicht nicht aus, um das Problem komplett zu beheben, Stichwort "Dreierregel". Was ist jetzt besser? Na das hier:

    class Person
    {
    public:
      explicit Person(const char* n)
      {
        name = n;
      }
    private:
      string name; // <-- kein Zeiger mehr! Warum auch?!
    };
    

    oder noch besser (mit Initialisierungsliste):

    class Person
    {
    public:
      explicit Person(const char* n)
      : name(n)
      {}
    private:
      string name;
    };
    

    Im vorherigen Beispiel wird das String-Objekt quasi vor der öffnenten geschweiften Klammer des Konstruktors "default-konstruiert" (leere Zeichenkette im Fall von string) und dann später einen neuen Wert zugewiesen. Im letzten Beispiel wird über die Initialisierungsliste das string-Objekt direkt mit einer Zeichenkette initialisiert. Und das ist gut so.

    Ohne Zeiger kommt man in C++ relativ weit. Man kann ja all die Dinge aus der Standardbibliothek verwenden. Darunter gibt es die "Container". Wenn du wirklich das brauchst, was der dynamische Speicher bietet, nämlich eigene Kontrolle über die Lebenszeit eines Objekts, dann kann man natürlich immer noch mit Zeigern oder Zeiger-ähnlichen Dingen arbeiten. Spätestens dann musst du dir vorher beim Design überlegen, wer so ein Objekt "besitzt", also, wer dafür (inklusive Löschung) verantwortlich ist. In gutem C++ wirst du jedoch so gut wie nie ein delete finden und es ist trotzdem frei von Speicherlecks, weil man normalerweise die Verantwurtung/Verwaltung sofort irgend einem anderen Objekt überlässt so dass man sich darum nicht mehr selbst kümmern muss.

    Ich habe vor C++ auch Java gelernt und kann dir empfehlen, dir ein gutes C++ Buch zu besorgen. Das lohnt sich! Aber bevor du zuschlägst, schau dir auch mal ein paar Buchempfehlungen an. Ein Amazon-Top-Seller kann gerade bei C++ Büchern, totaler Müll sein, weil der Autor dir eventuell C als C++ verkauft und die Neulinge, die dem zum Opfer fallen und gute Bewertungen abgehen, nicht wissen, wie "gutes C++" aussieht.

    PS: VS 2005 ist uralt. Schnapp dir was neueres!



  • Habe hier gerade einmal durch die ersten Seiten geblättert. Es macht eine gute Figur gerade für Umsteiger, die schon Programmiererfahrung haben.

    Es gibt sogar einen Abschnitt 1.3.4 "Suggestions for Java programmers":

    C++ and Java are rather different languages with similar syntaxes. Their aims are significantly different and so are many of their application domains. Java is not a direct successor to C++ in the sense of a language that can do the same as its predecessor, but better and also more. To use C++ well, you need to adopt programming and design techniques appropriate to C++, rather than trying to write Java in C++. It's not an issue of remembering to delete objects that you create with new because you can't rely on the presence of a garbage collector:

    • ...
    • ...
    • ...

    Most of this advice applies equally to C# programmers.

    🙂

    Nee, ich verdiene nix an dieser Werbung.


Log in to reply