Unterschiede zu C++ für Umsteiger von Java



  • Hallo!
    Auch ich haeb mich vor kurzem dazu entschlossen mich mal näher mit C++ zu beschäftigen. Bisher habe ich hauptsächlich mit Java gearbeitet, daher meine Frage bzgl der Unterschiede der beiden Sprachen. Ich habe zwar schon gemerkt, dass man mit C++ systemnäher programmieren kann, dennoch würde mich ein grober Abriss über die Unterschiede mal interessieren.
    Wichtig erscheint mir vor allem die Tatsache, dass ich Programmiertechniken, die ich in Java verwende nicht einfach 1:1 in C++ übertrage, sondern auch die Möglichkeiten die C++ bietet völlig ausschöpfe.

    Welchen großen Unterschiede gibt es also, auf die man vor allem als Umsteiger genau schauen sollte? Und wie "zwinge" ich mich am effektivsten dazu, die C++ Möglickeiten komplett auszunutzen?

    Über Hinweise, Tipps und Tricks bin ich dankbar. 🙂

    Gruß
    der Umsteiger



  • Was mir auf Anhieb einfällt:

    • C++ hat keinen Garbage Collector (du mußt dich selber darum kümmern, wer wann den Speicher freigeben darf)
    • C++ bietet Mehrfachvererbung (sicher nützlich, aber nicht unbedingt ein MUSS für erfolgreiche Programmierer :D)
    • in C++ kannst du auch jenseits von Klassen arbeiten
    • ...


  • C++ kennt keine Packages
    -> Inhalte von Libs werden über Headerdateien verfügbar gemacht
    C++ erlaubt Mehrfachvererbung
    C++ kennt templates
    C++ kennt Zeiger
    Eintrittsfunktion "main()" nicht vom Typ "void" sondern i.d.R. vom Typ "int"



  • * C++ hat kein multithreading
    * C++ hat kein 'instanceof'
    * C++ hat kein eingebautes windowing
    * ...
    😉



  • Was mir auf Anhieb (zusätzlich) einfällt:

    • Während man in Java kurz kompiliert und dafür lang testet, ist es in C++ andersherum ("Compiletimefehler sind besser als Laufzeitfehler").
    • Was in Java "Referenz" heißt, kommt dem am nächsten, was in C++ "Zeiger" heißt.
    • In C++ gibt's außerdem noch "Referenzen" und "(Stack)Objekte" (das heißt, man kann das, was man mit "primitiven Typen machen kann, in C++ mit allen Typen machen).
    • C++ kennt "const Variablen".
    • Während in Java so ziemlich alles, was "J" im Namen hat, in den Standard aufgenommen hat, sind im C++-Standard nur recht wenige (dafür aber sehr allgemeingültige und wichtige) Dinge festgelegt.
    • Es ist in C++ sehr viel leichter, schlechten Code zu schreiben als in Java; aber man kann auch besseren schreiben als in Java ... 😉
    • man kann Operatoren überladen
    • strings sind in C++ echte Objekte
    • es gibt in C++ keine "verschachtelten Objekte" (bzw. das, was so aussieht, funktioniert ganz anders)
    • ...

    Ich hatte da mal so ein nettes Dokument von Eckels ("Thinking in ....") gesehen, in dem das gut rüberkommt.... mal sehen, ob ich das wiederfinde.
    EDIT: hier ! (ist allerdings "andersherum", aber kann trotzdem als Vergleich dienen)

    Gruß,

    Simon2.



  • Mir fällt sofort ein, das C++ eine Multiparadigmensprache ist. Nämlich das ich nicht OO-Programmierung machen muß, wo ich mit anderen Paradigmen erfolgreicher sein kann. Z.B. ist die Standard-Lib von C++ ein sehr schönes Beispiel dafür. Ich kann aber auch versuchen strikt OOP zu machen, wenn ich will.

    Das es solche Dinge wie keinen GC gibt, fällt mir ehrlich gesagt nicht sofort ein, weil es für mich normal ist, das ich auch einen GC trotzdem benutzen kann. Ich kann aber auch Smartpointer benutzen, wenn ich mich um das Aufräumen nicht kümmern will. Aber ich kann auch meistens auf Pointer verzichten, weil ich meistens Objekte auf dem Stack anlege oder als Values in einen Container packe. Komme ich meistens (nicht ausschliesslich!) ohne Pointer aus.



  • Artchi schrieb:

    ...
    Das es solche Dinge wie keinen GC gibt, fällt mir ehrlich gesagt nicht sofort ein,...

    ... und weil es für die meisten Programmieraufgaben gar keine Rolle spielt - ehrlich gesagt: Mit Stackobjekten (und Referenzen darauf) bekommt man schon seeeeehr viel hin !

    (Ich verstehe auch gar nicht, warum fast alle C++-Anfänger in Büchern/Tutorials als erstes auf Zeiger, char* und Arrays gehetzt werden .... das braucht man eigentlich eher selten und in Spezialfällen 👎 )

    Gruß,

    Simon2.



  • Hi,

    da ist ja schon einiges genannt worden. Ich kann mich dem nur anschliessen, daß Pointer in der Regel eher selten benötigt werden. Das ist auch meine Empfehlung an Java-Umsteiger: lege Objekte auf dem Stack an, statt mit new. Java-Programmierer sind es gewöhnt, daß Objekte mit new angelegt werden. Das solltest Du Dir gleich mal abgewöhnen.

    Eines der leistungsfähigsten und am wenigsten erwähnte Sprachmittel von C++ ist meiner Meinung nach der Destruktor. Er nimmt mir in den aller meisten Fällen nicht nur die Arbeit des GC ab, sondern kann auch weitere Resourcen frei geben. Wenn man die Aufräumarbeiten (also neben Speicher frei geben auch Transaktionen abschliessen, Dateihandles schliessen usw.) dem Destruktor überlässt, verliert der gefürchtete Memory-Leak (bzw. Resource-Leak) schnell an Schrecken.

    Und noch ein paar Hinweise zu diesen Kommentar:

    net schrieb:

    * C++ hat kein multithreading
    * C++ hat kein 'instanceof'
    * C++ hat kein eingebautes windowing
    * ...
    😉

    Multithreading kann man in C++ sehr wohl verwenden. Es ist halt nicht in der Standardbibliothek. Der Programmierer hat aber im Gegensatz zu Java vollen Zugriff zur Betriebssystem-API, wo er APIs zur Thread-Erzeugung findet.

    "instanceof" ist in der Regel schlechter Programmierstil. Trotzdem ist diese Argument falsch. Richtig formuliert heisst das: in C++ heisst 'instanceof' 'dynamic_cast' und wird anders aufgerufen.

    Windowing gibt es tatsächlich nicht. Da steht man halt vor der Qual der Wahl, welche Bibliothek man nimmt. Es ist ja nicht so, daß man keine GUIs programmieren kann.

    Tntnet



  • Super, genau so hatte ich mir das vorgestellt. 👍

    Vllt hat ja noch jemand Tipps wie tntnet, was ich mir so abgewöhnen bzw angewöhnen sollte.

    Schon mal danke an alle, habt mir auf jeden Fall gute Tipps zur Orientierung gegeben 🙂



  • tntnet schrieb:

    Und noch ein paar Hinweise zu diesen Kommentar:

    net schrieb:

    * C++ hat kein multithreading
    * C++ hat kein 'instanceof'
    * C++ hat kein eingebautes windowing
    * ...
    😉

    Multithreading kann man in C++ sehr wohl verwenden. Es ist halt nicht in der Standardbibliothek. Der Programmierer hat aber im Gegensatz zu Java vollen Zugriff zur Betriebssystem-API, wo er APIs zur Thread-Erzeugung findet.

    ist halt wie mit allem in C++ - man braucht externe libs.
    in java ist das threading aber schon eingebaut. C++ hat auch nix, was dem java keyword 'synchronized' entsprechen würde.

    tntnet schrieb:

    "instanceof" ist in der Regel schlechter Programmierstil.

    welch kühne behauptung...

    noch was:
    * c++ hat keine 'reflection api' (ich weiss, das ist nur was für leute mit schlechtem programmierstil) 😉
    * c++ unterstützt von haus aus keine webtechnologien (wie java mit servlets, applets, jsp, xml, soap...)



  • net schrieb:

    ...
    in java ist das threading aber schon eingebaut. C++ hat auch nix, was dem java keyword 'synchronized' entsprechen würde.
    ...
    * c++ hat keine 'reflection api' (ich weiss, das ist nur was für leute mit schlechtem programmierstil) 😉
    * c++ unterstützt von haus aus keine webtechnologien (wie java mit servlets, applets, jsp, xml, soap...)

    Das fällt alles unter

    Simon2 schrieb:

    ...

    ...

    • Während in Java so ziemlich alles, was "J" im Namen hat, in den Standard aufgenommen hat, sind im C++-Standard nur recht wenige (dafür aber sehr allgemeingültige und wichtige) Dinge festgelegt.

    ...

    "synchronizied" nutzt Dir in enterprise-Umgebungen ebenso wenig wie "von Haus aus webtechnology" und "reflection API" oder die "java-Standard-GUI"...

    Da darfst Du mit dem Zeug dem Framework sowieso nicht "reinpfuschen" ... da ist es einfacher, alles, was der Standard hergibt, verwenden zu können (wie in C++) als nur Teile davon.
    Wie gesagt: C++ ist ein "schmaler Standard" (aber dafür ein sehr stabiler) - für alles, was man in Java macht, gibt's auch C++-Libs.

    Gruß,

    Simon2.



  • der Umsteiger schrieb:

    ...
    Vllt hat ja noch jemand Tipps wie tntnet, was ich mir so abgewöhnen bzw angewöhnen sollte....

    Meine ersten Tipps:

    • Beim Design auf "Zuständigkeiten" achten ! Wem "gehört" ein Objekt und wer soll es (schreibend ? lesend ?) nutzen ? Das ist (nach meiner Erfahrung) für Java-Programmierer etwas ungewohnter und in C++ hast Du einige Möglichkeiten, das schon im Design sinnvoll festzuzurren.
    • Wenn Du "new" tippen willst: Stopp !!! Erst zweimal nachdenken, ob es wirklich notwendig ist - braucht man eher selten in C++.
    • Wenn Du casten willst: Stopp !!! Erst viermal nachdenken, ob es wirklich notwendig ist - braucht man noch viel seltener in C++.
    • Gleich zu Beginn mit STL anfangen (std::vector, std::string, ....).
    • Was fachlich eine Funktion ist, soll auch technisch eine sein; man muss nicht immer alles als Objekt entwerfen - oftmals ist es sinnlos.

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Wie gesagt: C++ ist ein "schmaler Standard" (aber dafür ein sehr stabiler) - für alles, was man in Java macht, gibt's auch C++-Libs.

    hast ja recht, aber man muss sich in C++ alles mühsam zusammensuchen und jeder kocht sein eigenes süppchen. in der hinsicht ist java einfach benutzerfreundlicher...



  • net schrieb:

    ...in der hinsicht ist java einfach benutzerfreundlicher...

    Finde ich eigentlich nicht.
    In Java sucht man genauso lange .. nur, dass eben alles "Standard" heißt - aber wenn ich eine bestimmte Funktionalität suche, muß ich mich ebenso durch Libs wühlen. ...
    Damit will ich nicht Java schlecht machen, sondern nur seinen vermeintlichen Vorteil relativieren.

    "Benutzerfreundlicher" ist Java IMO deutlich für Programmieranfänger ... man kommt einfach schneller aus den Startlöchern (vA als in C aber auch als in C++).

    Gruß,

    Simon2.



  • Naja, Java ist auch nur in der Basis nutzerfreundlich. Hier bei unserem Kunden ist es z.B. erforderlich, sich mit der Eclipse Platform auszukennen. Eclipse Platform ist auch ein "externes" Framework welches ich mir "suchen" muß. Und jeder der Java kann, muß nicht zwingend OSGI und Eclipse-Plugins kennen. Immerhin gibts ganze Bücher über dieses Framework! Irgendwie und irgendwann muß man immer auf externe Libs zugreifen. Ich kann nicht immer mit der Basis auskommen.

    Und synchronized ist zwar ein Java-Schlüsselwort aber so flexibel ist es dann doch nicht.

    Sicherlich, in C++ muß ich mir vieles mehr zusammen suchen, aber im Prinzip ist es egal. Weil den Endanwender meines Systems/Programms interessiert das nicht. Schlimm wäre es, wenn dadurch der Endanwender Probleme bekommt. Ich als Entwickler suche mir das einmal zusammen und programmiere. Wenn ich in einem Team bin, stelle ich eh alles über einen SCM wie Subversion oder CVS bereit. Also hat im Team eh nur einer die Aufgabe.

    Ich z.B. habe mir Boost eingerichtet. Das hab ich einmal gemacht und mein IDE kennt sie jetzt. Und, war das jetzt so schlimm?



  • Artchi schrieb:

    Naja, Java ist auch nur in der Basis nutzerfreundlich....

    Genau das meinte ich mit "für Anfänger" und "in enterprise environments relativiert sich das sehr schnell". 😃

    Gruß,

    Simon2.



  • der Umsteiger schrieb:

    Super, genau so hatte ich mir das vorgestellt. 👍

    Vllt hat ja noch jemand Tipps wie tntnet, was ich mir so abgewöhnen bzw angewöhnen sollte.

    Schon mal danke an alle, habt mir auf jeden Fall gute Tipps zur Orientierung gegeben 🙂

    - vermeide C-Style Coding, stattdessen:
    - benutze std::string und std::wstring
    - benutze std::vector und std::list
    - seit April gibts auch std::tr1:array
    - benutze ausgiebigg die Standard-Bibliothek, sie ist sehr flexibel und mächtig!
    - vermeide Makros, da sie fehleranfällig sind, C++ hat gute Ersatzkonstrukte
    - später würde ich noch Boost (eine Library Sammlung) benutzen



  • ok, mir haben die tipps auch was gebracht,
    wenn man aber von java kommt, sollte man oop programieren gewohnt sein(und das ist in c++ ja auch in ordnung).
    Da frag ich mich grad wie man das ohne zeiger machen soll?
    nur mit referenzen und stack objekten?
    Dazu braucht man doch schon nen zeiger, sonst kann man doch keine virtuellen funktionen aufrufen, oder?
    bin noch nicht wirklich erfahren, aber das hat mich jetzt schon verunsichert und verwirrt.
    Kommt ja auch wie schon gesagt auf die aufgabenstellung an.
    Wenn ich da auf dem holzweg bin muß ich das nun erfahren,
    gruß



  • Ja, das habe ich auch sehr lange geglaubt, das ausschliesslich über Pointer virtuelle bzw. polymorphe Aufrufe funktionieren. Ich bin auch der Meinung, das ich das aus dem Stroustrup-Buch habe. 🙄 Müsste ich mich aber nochmal vergewissern, das es in dem Buch drin stand.

    Aber das kannst du ja leicht selbst mal ausprobieren, um dich zu überzeugen. Hier mal mein Beispiel:

    #include <iostream>
    
    class base
    {
      public:
    	virtual void foo()
    	{ 
    		std::cout << "base::foo()" << std::endl;
    	}
    };
    
    class special : public base
    {
      public:
        virtual void foo()
    	{
    		std::cout << "special::foo()" << std::endl;
    	}
    };
    
    void bar(base &b)
    {
       b.foo(); // polymorpher Aufruf (late binding)
    }
    
    int main()
    {
        base b;
    	bar(b);
    
    	special s;
    	bar(s);
    }
    

    Ausgabe:

    base::foo()
    special::foo()
    

    Kein einziger Pointer und kein einziges new benutzt.



  • das war sehr überzeugend. danke, muß wohl ernsthaft umdenken.
    gruß


Anmelden zum Antworten