Ergebnis 1 bis 18 von 18

[C++] Vertiefung

  1. #1 Zitieren
    Deus Avatar von FlashX
    Registriert seit
    Oct 2007
    Ort
    R'lyeh
    Beiträge
    12.706
    Ich wollte eigentlich erst direkt jabu per PN anschreiben, da ich seine ausführlichen Beiträge in der PE und hier sehr zu schätzen weiß und ich keine Ahnung habe, wie tot dieses Forum ist - aber anstatt jemanden direkt zu belästigen, hoffe ich einfach mal, dass hier ab und zu noch jemand reinschaut.

    Ich hab 2016 mein Informatikstudium begonnen und im ersten Semester C++ gelernt (bzw. vertieft, da Vorkenntnisse vorhanden). Wir kamen damals, wenn ich mich recht erinnere, bis zu Iteratoren, Operator Overloading, Vererbung und Template-Programmierung. Zwar hab ich seitdem immer mal wieder einen kleinen Code geschrieben, um am Ball zu bleiben und mir unbekannte Bibliotheken zu erforschen, aber so richtig in Kontakt kam ich seitdem nicht mehr mit der Sprache.

    Hier und da mal ein bisschen C für Multithreading und nicht funktionierende Sockets (sehr spaßig, aber nicht meine erste Wahl), ein Software Engineering Projekt in Java (zum Kotzen, aber zumindest erster Kontakt mit GUI und Git), mittlerweile sehr viel Python (Machine Learning und persönliche Bequemlichkeit). Für nächstes Semester hab ich die Master-Vorlesung "OOP for Scientific Computing", die 2017 schon mit der Nutzung der neuen C++17 Features geworben hat, im Auge.

    Jedenfalls, worauf ich hinaus will: Aus irgendeinem Grund ist mir C++ immer im Herzen geblieben und aktuell für mich die Sprache, die ich neben Python beherrschen will. Habt ihr Vorschläge, welche Gebiete man sich unbedingt anschauen sollte, wenn man die Sprache vertiefen will? Gibt es vielleicht ein sehr empfehlenswertes aktuelles Buch?


    Wo ich schon dabei bin, kann ich natürlich noch ein paar wichtige Dinge nennen, die mir Probleme bereiten:

    Memory Management.
    Mein Dozent hat Pointer komplett vermieden, da er die Vorlesung lieber sehr anwendungsorientiert gestalten wollte, anstatt die Sprache detailliert auszuarbeiten - ich kenne sie also nur aus C und hab nicht wirklich ein Gefühl dafür, wann man sie in C++ sinnvoll verwendet.

    GUI.
    Ich kenne mich recht wenig damit aus und kam bislang nur mit SWT in Java in Kontakt, was ich eher ungeil fand. Dagegen ist der Windows Forms Editor in Visual Studio sehr komfortabel, aber eben für C#. Gibt es ähnliche Editoren für C++ bzw. sind diese empfehlenswert, welches Framework sollte man überhaupt verwenden? Meist lese ich Qt.

    Projektmanagement.
    In Java wird man quasi zu einer guten Struktur gezwungen, dadurch, dass man das gesamte Programm in sinnvolle kleinere Klassen aufspaltet, die jeweils eine eigene Datei darstellen. Wie regelt man das in C++? (Eine Frage, die mich schon seit Beginn des Studiums begleitet)
    ~ That is not dead which can eternal lie
    ~ And with strange aeons even death may die

    We shall swim out to that brooding reef in the sea and dive down through black abysses to Cyclopean and many-columned Y'ha-nthlei,
    and in that lair of the Deep Ones we shall dwell amidst wonder and glory for ever.
    FlashX ist offline

  2. #2 Zitieren
    Abenteurer Avatar von Feyn
    Registriert seit
    Dec 2016
    Beiträge
    68
    Zitat Zitat von FlashX Beitrag anzeigen
    Ich wollte eigentlich erst direkt jabu per PN anschreiben, da ich seine ausführlichen Beiträge in der PE und hier sehr zu schätzen weiß und ich keine Ahnung habe, wie tot dieses Forum ist - aber anstatt jemanden direkt zu belästigen, hoffe ich einfach mal, dass hier ab und zu noch jemand reinschaut.
    Hallo
    Ein paar Sachen, die mir spontan einfallen:

    Zitat Zitat von FlashX Beitrag anzeigen
    GUI.
    Ich kenne mich recht wenig damit aus und kam bislang nur mit SWT in Java in Kontakt, was ich eher ungeil fand. Dagegen ist der Windows Forms Editor in Visual Studio sehr komfortabel, aber eben für C#. Gibt es ähnliche Editoren für C++ bzw. sind diese empfehlenswert, welches Framework sollte man überhaupt verwenden? Meist lese ich Qt.
    Den Designer für WindowsForms in VisualStudio gibt es tatsächlich nicht nur für C#, sondern auch für C++/CLI (managed C++). Hat aber abgesehen von der ähnlichen Syntax nicht viel mit dem "normalen" C++ gemeinsam. Vielleicht gefällt dir das ja besser als C# .


    Zitat Zitat von FlashX Beitrag anzeigen
    Projektmanagement.
    In Java wird man quasi zu einer guten Struktur gezwungen, dadurch, dass man das gesamte Programm in sinnvolle kleinere Klassen aufspaltet, die jeweils eine eigene Datei darstellen. Wie regelt man das in C++? (Eine Frage, die mich schon seit Beginn des Studiums begleitet)
    Du kannst das ähnlich zu Java gestalten. Für jede Klasse kannst du eine eigene Header-Datei erstellen (.h), in die du die Definition der Klasse schreibst. Die Implementierung der Klasse kann entweder mit in die Header-Datei, oder in eine Source-Datei (.cpp, dies ist der übliche Weg).
    Damit hat man für jede Klasse zwei Dateien, die meistens gleich heißen (also beispielsweise String.h und String.cpp).
    Feyn ist offline

  3. #3 Zitieren
    Deus Avatar von FlashX
    Registriert seit
    Oct 2007
    Ort
    R'lyeh
    Beiträge
    12.706
    Zitat Zitat von Feyn Beitrag anzeigen
    Den Designer für WindowsForms in VisualStudio gibt es tatsächlich nicht nur für C#, sondern auch für C++/CLI (managed C++). Hat aber abgesehen von der ähnlichen Syntax nicht viel mit dem "normalen" C++ gemeinsam. Vielleicht gefällt dir das ja besser als C# .
    Ja nun, mein Problem ist nicht, dass ich C# nicht mag, sondern dass ich keinen Sinn darin sehe, mich in eine dritte Sprache einzuarbeiten

    Zitat Zitat von Feyn Beitrag anzeigen
    Du kannst das ähnlich zu Java gestalten. Für jede Klasse kannst du eine eigene Header-Datei erstellen (.h), in die du die Definition der Klasse schreibst. Die Implementierung der Klasse kann entweder mit in die Header-Datei, oder in eine Source-Datei (.cpp, dies ist der übliche Weg).
    Damit hat man für jede Klasse zwei Dateien, die meistens gleich heißen (also beispielsweise String.h und String.cpp).
    Danke, dann hatte ich wohl den richtigen Gedanken.
    ~ That is not dead which can eternal lie
    ~ And with strange aeons even death may die

    We shall swim out to that brooding reef in the sea and dive down through black abysses to Cyclopean and many-columned Y'ha-nthlei,
    and in that lair of the Deep Ones we shall dwell amidst wonder and glory for ever.
    FlashX ist offline

  4. #4 Zitieren
    Legende Avatar von jabu
    Registriert seit
    Jul 2011
    Beiträge
    7.328
    Zitat Zitat von FlashX Beitrag anzeigen
    Ja nun, mein Problem ist nicht, dass ich C# nicht mag, sondern dass ich keinen Sinn darin sehe, mich in eine dritte Sprache einzuarbeiten
    Dass Feyn grinst, sollte wohl nicht unbegründet sein. C++/CLI ist eine dritte Sprache (weswegen das nicht zum Lernen von C++ taugt) und zwar eine Perversion in sich, wenn du mich fragst. Nimm für das GUI C#/CLI/.NET, das ist füreinander geschaffen. Deinen C++-Code, z.B. für Ressourcen- oder Laufzeitkritisches (oder einfach für die Problemlösung, die im GUI nichts zu suchen hat), kannst du in eine DLL tun und von deiner GUI-Anwendung aus aufrufen. Einen guten Teil des Overheads und der Grobklotzigkeit, auf deren Meidung man bei C++ aus ist, hast du dir mit CLI/.NET sowieso eingehandelt. Mit Grundkenntnissen in C++ und Java (die du wohl haben dürftest, wenn ich dich richtig verstehe) sollte C# gut zugänglich sein. Besser lernst du das, als deine Zeit mit den Besonderheiten von C++/CLI zu verplempern. Letzteres kannst du immer noch, wenn du mal irgendwo anheuerst, wo das gefragt ist. Die Wahrscheinlichkeit, dass C++/CLI vorher ausgestorben ist, dürfte jedoch nicht ganz gering sein. Die Frage ist, ob du es dir erlauben willst, dein C++ so weit zu vergurken und mit Schrott anzureichern, dass du mit dem richtigen C++ und seinen Qualitäten nicht mehr rechtzeitig in die Spur kommst.

    Ich würde es umgekehrt machen, nämlich die standardkonformsten (striktesten) Einstellungen wählen, die der Compiler unterstützt, also nix Microsoft- oder GNU- Erweiterungen, nix Kompatibilität mit veraltetem Code. So vermeidet man, Mist zu lernen (der z.B. woanders nicht läuft oder nichts mit C++ zu tun hat). Selbst dann sind die Compiler nicht hundertprozentig standardkonform (was ein Vergleich untereinander oder mit Clang schon oft aufgedeckt hat), aber beinahe. Und ich würde, was C++ anbelangt, erst mal auf komplexe GUI-Frameworks verzichten, weil die nämlich eher nicht durch einen standardkonformen Compiler gehen und daher schlechte Angewohnheiten lernen lassen. Dann kannst du für GUI-Programmierung aktuelle Windows-Header einbinden, die schon einigermaßen dicht am Standard dran sein sollten, wobei du die Einstellungen nur so weit wie unbedingt nötig lockerst (überlege stets vorher, ob du vielleicht doch eine Header-Datei vergessen oder Mist hingeschrieben hast, bevor du etwas lockerst). Und dann machst du für das GUI direkte WIN-API-Programmierung, also mit einer Message Loop und Fensterprozedur(en). Dabei scheint so manches von der Betriebssystemarchitektur durch, weswegen das lehrreich ist. Wenn du das Konzept gerafft hast, dann solltest du auch eine ungefähre Vorstellung davon haben, wie GUI-Frameworks ticken (da sie auf solchem Kram aufbauen oder ihn implementieren) und sie fortan reflektierter benutzen. Dieser Erkenntnisgewinn kann bei fertigen Frameworks ziemlich lange auf sich warten lassen. Danach kannst du dich immer noch z.B. in QT, MFC oder wxWidgets (oder etwas Schlankeres) einarbeiten, zumal das ähnlich aufwendig wie das Erlernen einer Programmiersprache ist und daher gut bedacht sein will, bevor man tiefer einsteigt. Bevor dein C++ einigermaßen gefestigt ist, dürften solche Frameworks nicht gut sein. Zudem verleiten sie dazu, dass sich alles nur noch darum dreht, anstatt dass man mit C++ echte Probleme löst. Deswegen würde ich den GUI-Kram nicht ausufern lassen, es sei denn, es geht dir darum. Man kann "unendlich" viel Zeit damit verbringen, während man bei C++ nichts hinzulernt.

    Damit will ich nicht behaupten, es besser zu wissen, denn Prognosen sind schwierig, wenn sie die Zukunft betreffen™. Man darf es also als Gedankenanstöße interpretieren.

    Danke, dann hatte ich wohl den richtigen Gedanken.
    Ergänzend:
    • Verwende dazu von Anfang an Include-Guards (die echten, nicht #pragma once (es sei denn, du hast einen Grund dafür, dann nimmst du aber besser beides)).
    • Bedenke die ODR (One Definition Rule). Innerhalb der Klassendefinition definierte Memberfunktionen sind implizit inline, weswegen sie auch bei mehrfacher Einbindung nicht kollidieren. Separate Definitionen sind normalerweise in einer Quelldatei am besten untergebracht und zwar in genau einer, damit sie nicht die ODR verletzen (würden beim Linken kollidieren). Wären sie in der Header-Datei untergebracht, so käme es, anders als bei inline, zu Mehrfachdefinition, was eine Verletzung der ODR wäre.
    • Sowohl Header- als auch Quell-Dateien sollten immer alle zu ihrer Übersetzung nötigen Header-Dateien einbinden, sodass es auf die Reihenfolge nicht ankommt. Wenn man die nicht durcheinanderwürfeln kann, ist etwas faul und an der Ursache anzusetzen (anstatt umzustellen, bis es durch den Compiler geht). Sonst werden die Probleme mit der Projektgröße tendenziell schlimmer, bis irgendwann keine Reihenfolge mehr funktioniert (bricht dann jeweils woanders).
    • Vermeide zyklische Abhängigkeiten von Header-Dateien. Kleinere Einheiten (z.B. zu jeweils einer Klasse) können ein Ausweg sein. Zwar können Vorwärtsdeklarationen in Fällen, wo der Compiler die Implementierung nicht sehen muss, manchmal aus der Patsche helfen, aber das sollte nicht davon entbinden, die Ursache abzustellen. Ein Drumherummogeln mit Zeigertricksereien kann die Performance verschlechtern oder schlimmere Probleme einführen.
      Es gibt aber auch Fälle, bei denen die zyklische Abhängigkeit nicht am Aufbau der Dateien liegt, sondern direkt am Klassendesign, indem die eine mit der anderen etwas anstellt und umgekehrt. Dann können oftmals freie Funktionen (die man evtl. überlädt), einen Ausweg bieten (es war unnötig oder widernatürlich, den jeweils anderen Typ durch eine Memberfunktion zu verarbeiten). Bei den freien Funktionen müssen die Typen dem Compiler zwar auch bekannt sein, aber die eine Header-Datei muss nicht mehr die andere einbinden und umgekehrt (was nicht geht). Stattdessen bindet diejenige Header-Datei, die z.B. freie Inline-Funktionen enthält, die Header-Dateien der beiden, dann nicht mehr voneinander abhängigen, Typen ein.
    • Bei nicht mehr ganz kleinen Projekten hat sich eine Aufteilung zu kleineren Einheiten bewährt, bei denen die darin enthaltenen Einheiten jeweils ihre Header-Dateien nicht exponieren. Das funktioniert natürlich nur so weit, wie die gobale Header-Datei ihrerseits die inneren Typen nicht verwendet. Manchmal muss sie das nämlich leider doch mehr oder minder, z.B. aus Performancegründen.
    • Der sogar "in besten Kreisen" manchmal geäußerte Rat, Deklarationen bezüglich anderer Übersetzungseinheiten doch anstatt in Header-Dateien in den Quelldateien, die diese benötigen, anzubringen, um die Header-Dateien zu verschlanken und damit den Übersetzungsprozess zu beschleunigen, führt bei großen Projekten durch Inkonsistenzen geradezu in die Hölle. Es kommt nicht nur zu nicht aktualisierten Deklarationsdoubletten, sondern auch im Rahmen von Überarbeitungen zu unfreiwilligen Überladungen oder dem Aufruf falscher Funktionen. Etwas zu "importieren", von dem man nicht mal weiß, wie der entsprechende "Export" aussehen würde, konterkariert den Zweck des "Exportierens". Der erhöhte Wartungsaufwand und die Bugs überwiegen den mickrigen Zeitgewinn doch bei weitem. Solche Ratschläge dürften spätestens bei Hardware aus rund den letzten eineinhalb Jahrzehnten obsolet sein. Und wo man das dennoch so deutlich merkt, dass es stört, dürfte in den allermeisten Fällen der Code schlecht organisiert sein.

    Ich muss hier erst mal einen Schnitt machen.
    jabu ist offline Geändert von jabu (30.01.2019 um 07:49 Uhr)

  5. #5 Zitieren
    Abenteurer Avatar von Feyn
    Registriert seit
    Dec 2016
    Beiträge
    68
    Zitat Zitat von FlashX Beitrag anzeigen
    Memory Management.
    Mein Dozent hat Pointer komplett vermieden, da er die Vorlesung lieber sehr anwendungsorientiert gestalten wollte, anstatt die Sprache detailliert auszuarbeiten - ich kenne sie also nur aus C und hab nicht wirklich ein Gefühl dafür, wann man sie in C++ sinnvoll verwendet.
    Ein paar Worte zum Memory-Mangement und zur Anwendung von Pointern:
    Pointer (bzw. Referenzen) werden meist als Funktionsübergabeparameter verwendet.
    Du weißt bestimmt schon, dass Parameter in C/C++ standardmäßig by value übergeben werden.
    Dadurch wird bei der Übergabe eine Kopie angelegt, sodass eine Änderung des Parameters innerhalb der Funktion keine Auswirkung auf den Aufrufer hat.
    Falls man also möchte, dass eine Funktion die Eingabeparameter überschreibt, so kann man die Parameter als Referenz (&) oder Pointer (*) deklarieren.
    (Ich weiß leider nicht, ob ich dir gerade nur bereits Bekanntes erzähle )

    Ansonsten werden Pointer auch in C++ oft für dynamische Speicher-Allokation verwendet, z.B. wenn die Größe eines Arrays nicht zur Compilezeit bekannt ist.
    Der dafür benötigte Speicher wird vom Heap reserviert. In C kennst du das bestimmt unter der Funktion "malloc".
    In C++ dagegen wird dagegen meist der Operator "new" verwendet:
    int anzahl = 5;
    int* x = new int[anzahl];
    Wichtig ist, dass Speicher der vom Heap allokiert wurde, auch vom Programmierer wieder freigegeben werden muss.
    Dafür gilt:
    malloc -> free
    new -> delete

    Beispiele zur den Speicherarten:
    Stack storage
    Deklaration einer Variablen in einer Funktion:
    int x = 1;
    Der belegte Speicher wird mit dem Rücksprung der Funktion wieder vom Stapel genommen.
    (Deswegen muss der Programmierer hier auch keinen Speicher freigeben)

    Heap storage
    Dynamische Allokation auf dem Heap:
    Entity* entity = new Entity;
    Der Programmierer muss den belegten Speicher selbst wieder freigeben.
    Der Heap wird vom Betriebssystem überprüft und falls notwendig defragmentiert.

    Static storage

    Für globale oder statische (Klassen-)Variablen.
    Der Speicher wird quasi mit dem Start des Programmes belegt und initialisiert.
    Er wird mit dem Beenden der Anwendung wieder freigegeben.

    Register storage
    Für elementare Datentypen, wird automatisch vom Compiler festgelegt.
    Auf diesen Speicher kann die CPU am schnellsten zugreifen.

    Theoretisch ist dieses Wissen heute keine Notwendigkeit mehr, weil die meisten Einsatzgebiete von Pointern durch Templates aus der Standardbibliothek umgangen werden können (ob das positiv oder negativ ist, ist eine andere Frage).
    Trotzdem erhöht die Kenntnis der Funktionsweise von Pointern das allgemeine Verständnis von Code (auch in anderen Programmiersprachen).

    Übrigens: Wenn du an diesen elementaren Sachen interessiert bist, kannst du dir auch die Assembly deines geschriebenen SourceCodes ausgeben lassen. Das hat mir beispielsweise geholfen, die Vorgänge der Sprache besser zu verstehen.

    Bezüglich der Vertiefung in C++
    Letztendlich ist die Frage, in welche Richtung deine Interessen gehen. Die Möglichkeiten der Vertiefung sind fast endlos. Beispielsweise ist alleine schon die Template-Metaprogrammierung turing-vollständig.
    Mögliche Bereiche zur Vertiefung wären...
    - Die neuesten C++ Standards
    - Die C++ Standard-Bibliothek
    - Template-Meta-Programming
    - C++ Compiler-Optimierung
    - Verfahren zum Memory-Management
    - Die Windows API (welche jabu ja schon erwähnte)
    - Design-Patterns für C++
    ...

    jabu wird bestimmt noch mehr dazu sagen können. Er hat definitiv mehr Erfahrung als ich, und eine Menge guter Tipps im Ärmel .
    Ich hoffe, mein Text war trotzdem ein bisschen hilfreich.
    Feyn ist offline Geändert von Feyn (30.01.2019 um 14:32 Uhr)

  6. #6 Zitieren
    Deus Avatar von FlashX
    Registriert seit
    Oct 2007
    Ort
    R'lyeh
    Beiträge
    12.706
    Zitat Zitat von jabu Beitrag anzeigen
    Deinen C++-Code, z.B. für Ressourcen- oder Laufzeitkritisches (oder einfach für die Problemlösung, die im GUI nichts zu suchen hat), kannst du in eine DLL tun und von deiner GUI-Anwendung aus aufrufen. Einen guten Teil des Overheads und der Grobklotzigkeit, auf deren Meidung man bei C++ aus ist, hast du dir mit CLI/.NET sowieso eingehandelt. Mit Grundkenntnissen in C++ und Java (die du wohl haben dürftest, wenn ich dich richtig verstehe) sollte C# gut zugänglich sein.
    C# ist mir nicht allzu fremd, aber an den Ansatz mit den DLLs hab ich tatsächlich noch gar nicht gedacht. Kompiliert man diese ähnlich wie eine EXE, bzw. ist das bei DLLs auch mit einem Cross Compiler von Linux aus möglich?

    Zitat Zitat von jabu Beitrag anzeigen
    Dann kannst du für GUI-Programmierung aktuelle Windows-Header einbinden, die schon einigermaßen dicht am Standard dran sein sollten, wobei du die Einstellungen nur so weit wie unbedingt nötig lockerst (überlege stets vorher, ob du vielleicht doch eine Header-Datei vergessen oder Mist hingeschrieben hast, bevor du etwas lockerst). Und dann machst du für das GUI direkte WIN-API-Programmierung, also mit einer Message Loop und Fensterprozedur(en). Dabei scheint so manches von der Betriebssystemarchitektur durch, weswegen das lehrreich ist. Wenn du das Konzept gerafft hast, dann solltest du auch eine ungefähre Vorstellung davon haben, wie GUI-Frameworks ticken (da sie auf solchem Kram aufbauen oder ihn implementieren) und sie fortan reflektierter benutzen. Dieser Erkenntnisgewinn kann bei fertigen Frameworks ziemlich lange auf sich warten lassen. Danach kannst du dich immer noch z.B. in QT, MFC oder wxWidgets (oder etwas Schlankeres) einarbeiten, zumal das ähnlich aufwendig wie das Erlernen einer Programmiersprache ist und daher gut bedacht sein will, bevor man tiefer einsteigt. Bevor dein C++ einigermaßen gefestigt ist, dürften solche Frameworks nicht gut sein. Zudem verleiten sie dazu, dass sich alles nur noch darum dreht, anstatt dass man mit C++ echte Probleme löst. Deswegen würde ich den GUI-Kram nicht ausufern lassen, es sei denn, es geht dir darum. Man kann "unendlich" viel Zeit damit verbringen, während man bei C++ nichts hinzulernt.
    Das ist ein sehr gutes Argument

    Zitat Zitat von jabu Beitrag anzeigen
    Bei nicht mehr ganz kleinen Projekten hat sich eine Aufteilung zu kleineren Einheiten bewährt, bei denen die darin enthaltenen Einheiten jeweils ihre Header-Dateien nicht exponieren. Das funktioniert natürlich nur so weit, wie die gobale Header-Datei ihrerseits die inneren Typen nicht verwendet. Manchmal muss sie das nämlich leider doch mehr oder minder, z.B. aus Performancegründen.
    Mit dem Wissen, wie der Präprozessor grob funktioniert, sind die Punkte alle sehr einleuchtend. Diesen hab ich allerdings nicht verstanden.

    Zitat Zitat von Feyn Beitrag anzeigen
    Ein paar Worte zum Memory-Mangement und zur Anwendung von Pointern:

    [...]

    Theoretisch ist dieses Wissen heute keine Notwendigkeit mehr, weil die meisten Einsatzgebiete von Pointern durch Templates aus der Standardbibliothek umgangen werden können (ob das positiv oder negativ ist, ist eine andere Frage).
    Trotzdem erhöht die Kenntnis der Funktionsweise von Pointern das allgemeine Verständnis von Code (auch in anderen Programmiersprachen).
    Sorry, ich hätte wohl direkt näher darauf eingehen sollen, hatte mich dann aber doch irgendwie dagegen entschieden. Die verschiedenen Speicherarten sind mir bekannt. Pointer ebenso - verkettete Listen und dynamische Arrays in C sind mir nicht fremd.
    Mein Problem ist eher Folgendes: Während Pointer in C unumgehbar sind, benötigt man sie dort an vielen Stellen, an denen man sie in C++ meidet. C-Funktionen wie malloc und calloc haben in C++ nichts mehr zu suchen. Anstatt Pointer auf Arrays als Funktionsparameter zu übergeben, übergebe ich direkt einen Vector oder ein anderes Array-Objekt, was sich dann auch sehr gut templatisieren lässt. Möchte ich Seiteneffekte, pack ich mir keinen Pointer, sondern eine Referenz. Iteratoren sind streng genommen Pointer, aber ihre Funktionsweise ist dann doch etwas anders.
    Kurz: Mir ist unklar, wo Pointer in C++ noch relevant sind. Klar, initialisiere ich alles auf dem Stack, ist der Speicher bei großen Programmen schnell zu Ende. Aber woher weiß ich, wann ich Speicher auf dem Heap alloziere und wann nicht?

    Zitat Zitat von Feyn Beitrag anzeigen
    Bezüglich der Vertiefung in C++
    Letztendlich ist die Frage, in welche Richtung deine Interessen gehen. Die Möglichkeiten der Vertiefung sind fast endlos. Beispielsweise ist alleine schon die Template-Metaprogrammierung turing-vollständig.
    Mögliche Bereiche zur Vertiefung wären...
    - Die neuesten C++ Standards
    - Die C++ Standard-Bibliothek
    - Template-Meta-Programming
    - C++ Compiler-Optimierung
    - Verfahren zum Memory-Management
    - Die Windows API (welche jabu ja schon erwähnte)
    - Design-Patterns für C++
    ...
    Also im Prinzip erst einmal die Standard-Bibliothek durcharbeiten und sich an moderne Standards gewöhnen. Etwas in der Richtung hab ich schon erwartet - ich kann nur schlecht einschätzen, ob es irgendwelche Bibliotheken/Features gibt, die für C++-Programmierer wirklich unabdinglich sind und die man sich näher anschauen sollte.

    Vielen Dank für die sehr ausführlichen Antworten
    ~ That is not dead which can eternal lie
    ~ And with strange aeons even death may die

    We shall swim out to that brooding reef in the sea and dive down through black abysses to Cyclopean and many-columned Y'ha-nthlei,
    and in that lair of the Deep Ones we shall dwell amidst wonder and glory for ever.
    FlashX ist offline Geändert von FlashX (30.01.2019 um 15:39 Uhr)

  7. #7 Zitieren
    Abenteurer Avatar von Feyn
    Registriert seit
    Dec 2016
    Beiträge
    68
    Zitat Zitat von FlashX Beitrag anzeigen
    Sorry, ich hätte wohl direkt näher darauf eingehen sollen, hatte mich dann aber doch irgendwie dagegen entschieden. Die verschiedenen Speicherarten sind mir bekannt. Pointer ebenso - verkettete Listen und dynamische Arrays in C sind mir nicht fremd.
    Gut! Ich hatte mich schon etwas gewundert, aber dann eben auch nicht mehr nachgefragt

    Zitat Zitat von FlashX Beitrag anzeigen
    Kurz: Mir ist unklar, wo Pointer in C++ noch relevant sind. Klar, initialisiere ich alles auf dem Stack, ist der Speicher bei großen Programmen schnell zu Ende. Aber woher weiß ich, wann ich Speicher auf dem Heap alloziere und wann nicht?
    Naja, wie du ja selbst schreibst, entweder wenn du sehr große Mengen benötigst, oder es erforderlich ist, den Speicher vor dem Rücksprung der Funktion freizugeben.
    Oder dein Programm erfordert es, dass ein Objekt eben NICHT mit dem Rücksprung der Funktion zerstört wird.

    Ansonsten nutzt man eher den Stack, welcher dem Heap gegenüber einige Vorteile hat (Performance, keine Memory-Leaks, du kennst das ja).

    Spezialfälle wie Cache-Optimierung und StructureOfArrays mal ausgenommen.

    Zitat Zitat von FlashX Beitrag anzeigen
    Also im Prinzip erst einmal die Standard-Bibliothek durcharbeiten und sich an moderne Standards gewöhnen. Etwas in der Richtung hab ich schon erwartet - ich kann nur schlecht einschätzen, ob es irgendwelche Bibliotheken/Features gibt, die für C++-Programmierer wirklich unabdinglich sind und die man sich näher anschauen sollte.
    Das hängt ganz von deinen Zielen ab. In manchen Firmen wird auch keine Standardbibliothek, sondern eine eigene Implementierung verwendet.
    Nicht zuletzt gibt es auch einige interessante Programmierer, die die OOP-Features von C++ ablehnen, C++ aber trotzdem verwenden.
    Ein Beispiel dafür ist das Projekt Handmade Hero - dort geht es um die Entwicklung eines Spiels von Beginn an, ohne fremde Bibliotheken.
    Es gibt also (leider) nicht wirklich unabdingbare Elemente. Mit der Standardbibliothek ist man allerdings immer gut beraten, weil sie eben trotzdem noch "standard" ist .

    Wenn du die Möglichkeit hast, mit dem Veranstalter deiner Master-Vorlesung Kontakt aufzunehmen, könntest du auch dort mal nachfragen, auf was genau dort Wert gelegt wird.
    Feyn ist offline Geändert von Feyn (30.01.2019 um 17:21 Uhr)

  8. #8 Zitieren

    Batmanistrator
    Avatar von Thoronador
    Registriert seit
    Jul 2005
    Ort
    Morrowind, Vvardenfell-Distrikt
    Beiträge
    20.405
    Zitat Zitat von FlashX Beitrag anzeigen
    Jedenfalls, worauf ich hinaus will: Aus irgendeinem Grund ist mir C++ immer im Herzen geblieben und aktuell für mich die Sprache, die ich neben Python beherrschen will. Habt ihr Vorschläge, welche Gebiete man sich unbedingt anschauen sollte, wenn man die Sprache vertiefen will? Gibt es vielleicht ein sehr empfehlenswertes aktuelles Buch?
    Keine direkte Buchempfehlung, sondern eine Blog-Empfehlung: Modernes C++ von Rainer Grimm. Zwar habe ich da auch bei Weitem nicht alles gelesen, aber ich fand das, was ich gelesen habe, immer ganz hilfreich. Aber der Mann schreibt auch Bücher über C++, da lässt sich vielleicht auch etwas finden, was dich interessiert.

    Außerdem ist ein Blick auf die C++ Core Guidelines nicht schlecht. Ja, das ist sehr umfangreich, und das muss man auch nicht komplett lesen, aber wenn man sich immer mal einen Abschnitt zu dem Thema herauspickt, mit dem man sich gerade beschäftigt.

    Zitat Zitat von FlashX Beitrag anzeigen
    Projektmanagement.
    In Java wird man quasi zu einer guten Struktur gezwungen, dadurch, dass man das gesamte Programm in sinnvolle kleinere Klassen aufspaltet, die jeweils eine eigene Datei darstellen. Wie regelt man das in C++? (Eine Frage, die mich schon seit Beginn des Studiums begleitet)
    In Java wird man zu guter Struktur gezwungen? Habe ich etwas verpasst? In Java hält dich auch keiner davon ab, alles in eine *.java-Datei zu schreiben. Sollte man natürlich nicht machen, wenn's mehr als ein Hello World-Beispiel werden soll, aber machen kann man es.

    Grundsätzlich kann man aber das gleiche Prinzip auch auf C++ anwenden: Für jede Klasse eine eigene Datei - bzw. zwei: eine Headerdatei (.h) und eine Datei mit der Implementierung (.cpp). In den Headern von vornherein immer #include-Guards verwenden, sonst wird man bei größeren Projekten nicht mehr froh.

    Zitat Zitat von FlashX Beitrag anzeigen
    Memory Management.
    Mein Dozent hat Pointer komplett vermieden, da er die Vorlesung lieber sehr anwendungsorientiert gestalten wollte, anstatt die Sprache detailliert auszuarbeiten - ich kenne sie also nur aus C und hab nicht wirklich ein Gefühl dafür, wann man sie in C++ sinnvoll verwendet.
    Kurz gesagt: Vermeide Pointer in C++.
    Für die Dinge, die man in C noch Pointer genutzt hat, kann man in C++ Referenzen oder andere Konstrukte verwenden. In modernem C++-Code wird man kaum noch sehen, dass jemand Pointer direkt einsetzt. Bzw. sollte man das nicht. Die meisten Pointer in C++ kommen meiner Erfahrung nach daher, dass man entweder alten C-Code nach C++ portiert und dabei die Pointer beibehalten hat, oder durch Einbindung von Drittbibliotheken, die in C geschrieben sind und daher auf Pointer angewiesen sind.

    Zitat Zitat von Feyn Beitrag anzeigen
    Falls man also möchte, dass eine Funktion die Eingabeparameter überschreibt, so kann man die Parameter als Referenz (&) oder Pointer (*) deklarieren.
    Für sowas nimmt man in C++ bitte nur noch Referenzen und keine Pointer. Das ist erstens sicherer (sowohl in der Handhabung als auch bei der Typsicherheit) und zweitens können Referenzen vom Compiler oft auch besser optimiert werden als Pointer.

    Zitat Zitat von Feyn Beitrag anzeigen
    Ansonsten werden Pointer auch in C++ oft für dynamische Speicher-Allokation verwendet, z.B. wenn die Größe eines Arrays nicht zur Compilezeit bekannt ist.
    Der dafür benötigte Speicher wird vom Heap reserviert. In C kennst du das bestimmt unter der Funktion "malloc".
    In C++ dagegen wird dagegen meist der Operator "new" verwendet:
    int anzahl = 5;
    int* x = new int[anzahl];
    Wichtig ist, dass Speicher der vom Heap allokiert wurde, auch vom Programmierer wieder freigegeben werden muss.
    Dafür gilt:
    malloc -> free
    new -> delete
    new/delete und malloc/free sollte man in C++ nach Möglichkeit vermeiden. Dafür gibt es Alternativen. Für ein Array, dessen Größe zur Compilezeit nicht bekannt ist, kann man sehr gut std::vector einsetzen. Überhaupt ist in den meisten Fällen, wo man in C++ eine Art von Container für mehrere Objekte vom gleichen Typ benötigt, std::vector die erste Wahl. Wenn du ein dynamisches Array haben willst, nimm std::vector. Wenn du eine Liste haben willst, nimm std::vector (und nicht std::list, weil linked lists langsam(er) sind). Wenn du einen Container brauchst, aber std::vector nicht magst, nimm std::vector.

    new/delete und malloc/free bergen auch immer die Gefahr von Speicherlecks. Das kann beispielsweise passieren, wenn man bei einem Pfad das delete vergisst. Die Abfolge ist ja im Prinzip immer:
    Code:
    int func()
    {
      MyClass* a = new MyClass();
      // do something
      delete a;
      return 5;
    }
    Oft kann "// do something" Schleifen, Verzweigungen, weitere Funktionsaufrufe, vorzeitiges return, etc. enthalten, und dann wird's unübersichtlich, sodass man da mal ein delete vergisst. Selbst wenn der Code zwischen new und delete überschaubar einfach ist, kann es passieren, dass in diesen Zeilen eine Exception auftritt und damit das delete nie erreicht wird. Schon hat man ein Speicherleck. Daher gilt: Wenn man das Objekt ohnehin nicht irgendwo als Pointer weitergeben muss, dann einfach direkt auf dem Stack anlegen:
    Code:
    int func()
    {
      MyClass a;
      // do something
      return 5;
    }
    Wenn's wirklich unbedingt ein Pointer sein muss, dann kann man sich mit Smart Pointern behelfen, die automatisch für die Freigabe der Objekte sorgen, sobald der Geltungsbereich des Smart Pointer verlassen wird:
    Code:
    int func()
    {
      std::shared_pointer<MyClass> a = std::make_shared<MyClass>();
      // do something
      return 5;
    }
    Zitat Zitat von Feyn Beitrag anzeigen
    Übrigens: Wenn du an diesen elementaren Sachen interessiert bist, kannst du dir auch die Assembly deines geschriebenen SourceCodes ausgeben lassen. Das hat mir beispielsweise geholfen, die Vorgänge der Sprache besser zu verstehen.
    Eine Ausgabe als Assemblycode braucht man heutzutage eigentlich nicht mehr - zumal die meisten C++-Compiler mittlerweile ohnehin so gut optimieren, dass man da nicht noch Assemblyanweisungen vergleichen und anpassen muss, um Geschwindigkeitsvorteile zu erhalten. Viel wichtiger ist, dass man erstmal gute Algorithmen hat. D.h. sortieren sollte man bei einem std::vector mit einer Million Elementen vielleicht nicht mit selbst gebauten Bubble Sort.

    Wenn man sich dennoch für die Assembly interessiert, gibt es da ein schickes Tool: den Compiler Explorer von Matt Godbolt.

    Zitat Zitat von FlashX Beitrag anzeigen
    Kurz: Mir ist unklar, wo Pointer in C++ noch relevant sind.
    Im Wesentlichen gibt es da zwei Punkte, wo "nackte" Pointer hauptsächlich noch auftauchen:
    • beim Modernisieren von altem C/C++ Legacy Code
    • in der Implementierung von (STL-)Container

    Ansonsten nutzt man da eigentlich meist andere Mittel oder Smart Pointer.

    Zitat Zitat von FlashX Beitrag anzeigen
    Also im Prinzip erst einmal die Standard-Bibliothek durcharbeiten und sich an moderne Standards gewöhnen. Etwas in der Richtung hab ich schon erwartet - ich kann nur schlecht einschätzen, ob es irgendwelche Bibliotheken/Features gibt, die für C++-Programmierer wirklich unabdinglich sind und die man sich näher anschauen sollte.
    Die einzige Bibliothek (neben der STL), die man aber über viele Gebiete hinweg sieht, ist Boost bzw. manche der Boost-Bibliotheken. Danach kommt gefühlt erstmal eine Ewigkeit nichts, und alles danach hängt vom Einsatzgebiet bzw. von der Aufgabe des Programmes ab.
    Thoronador ist offline

  9. #9 Zitieren
    Deus Avatar von FlashX
    Registriert seit
    Oct 2007
    Ort
    R'lyeh
    Beiträge
    12.706
    Zitat Zitat von Thoronador Beitrag anzeigen
    Keine direkte Buchempfehlung, sondern eine Blog-Empfehlung: Modernes C++ von Rainer Grimm. Zwar habe ich da auch bei Weitem nicht alles gelesen, aber ich fand das, was ich gelesen habe, immer ganz hilfreich. Aber der Mann schreibt auch Bücher über C++, da lässt sich vielleicht auch etwas finden, was dich interessiert.

    Außerdem ist ein Blick auf die C++ Core Guidelines nicht schlecht. Ja, das ist sehr umfangreich, und das muss man auch nicht komplett lesen, aber wenn man sich immer mal einen Abschnitt zu dem Thema herauspickt, mit dem man sich gerade beschäftigt.
    Vielen Dank, werde ich mir die Tage mal anschauen

    Zitat Zitat von Thoronador Beitrag anzeigen
    In Java wird man zu guter Struktur gezwungen? Habe ich etwas verpasst? In Java hält dich auch keiner davon ab, alles in eine *.java-Datei zu schreiben. Sollte man natürlich nicht machen, wenn's mehr als ein Hello World-Beispiel werden soll, aber machen kann man es.
    Okay, "gezwungen" ist das falsche Wort. Es ist nur sehr bequem, da man in modernen IDEs Klassen beinahe schon automatisch in Paketen organisiert. Ich muss aber auch dazu sagen, dass ich in C++ nie wirklich mit einer IDE gearbeitet habe - ich bin einfach kein Fan von IDEs. Vielleicht hat mir auch einfach deshalb die Antwort auf meine Frage gefehlt

    Zitat Zitat von Thoronador Beitrag anzeigen
    Die einzige Bibliothek (neben der STL), die man aber über viele Gebiete hinweg sieht, ist Boost bzw. manche der Boost-Bibliotheken. Danach kommt gefühlt erstmal eine Ewigkeit nichts, und alles danach hängt vom Einsatzgebiet bzw. von der Aufgabe des Programmes ab.
    Stimmt, von Boost hab ich öfter gehört. Werde ich ebenfalls im Hinterkopf behalten
    ~ That is not dead which can eternal lie
    ~ And with strange aeons even death may die

    We shall swim out to that brooding reef in the sea and dive down through black abysses to Cyclopean and many-columned Y'ha-nthlei,
    and in that lair of the Deep Ones we shall dwell amidst wonder and glory for ever.
    FlashX ist offline

  10. #10 Zitieren
    Halbgott Avatar von Progrinator
    Registriert seit
    Apr 2018
    Ort
    München
    Beiträge
    9.174
    @ Thoronador aber wenn man sein Code ordenlich aufzieht, dann sollte man nicht in die Gefahrlaufen, das Speicherlecks auftreten. Was ich mich halt frage, gelten die Sachen die du schreibst auch für sehr Performance orientiertes Programmieren.

    Da ich im laufe meiner Ausbildung Java und ähnliches oberflächlich hatte, habe ich kein Blick für Inhaltliche Sachen dies bezüglich und wollte daher mal nach hacken.
    Progrinator ist offline

  11. #11 Zitieren
    Drachentöter Avatar von Weltenschmerz
    Registriert seit
    Sep 2005
    Beiträge
    4.230
    Beim Überfleigen liest sich das für mich so als könnte C++ Sachen die ein C# nicht kann.
    Ist das so?
    Und wenn ja kannst du mit bitte für Laien erklären was das ist?
    Ich bin sowas von Sig.
    Weltenschmerz ist offline

  12. #12 Zitieren
    Halbgott Avatar von Progrinator
    Registriert seit
    Apr 2018
    Ort
    München
    Beiträge
    9.174
    Zitat Zitat von Weltenschmerz Beitrag anzeigen
    Beim Überfleigen liest sich das für mich so als könnte C++ Sachen die ein C# nicht kann.
    Ist das so?
    Und wenn ja kannst du mit bitte für Laien erklären was das ist?
    Du kannst mit C# nicht so nativ gehen, wie mit C++. Bei C# hast du zb. den garbage collector der sich um Sachen kümmert, die man in C++ manuell selbst konfiguriert.
    Progrinator ist offline

  13. #13 Zitieren
    Pretty Pink Pony Princess  Avatar von Multithread
    Registriert seit
    Jun 2010
    Ort
    Crystal Empire
    Beiträge
    11.228
    Zitat Zitat von Progrinator Beitrag anzeigen
    Du kannst mit C# nicht so nativ gehen, wie mit C++. Bei C# hast du zb. den garbage collector der sich um Sachen kümmert, die man in C++ manuell selbst konfiguriert.
    Auch in C# kannst du selber für eine 'Gatrbage Collection' sorgen, das macht aber wenig sinn, da der GC ziemlich gut ist, in dem was er macht.

    Was du aber auch in C# beachten musst: Wenn du einem Wert einen festen Speicherplatz zuweist (z.B. damit du Ihn an eine native DLL senden kannst), musst du Ihn auch Manuel freigeben.
    [Bild: AMD_Threadripper.png] Bei Hardware gibt es keine eigene Meinung, bei Hardware zählen nur die Fakten.


    Probleme mit der Haarpracht? Starres Haar ohne Glanz? TressFX schafft Abhilfe. Ja, TressFX verhilft auch Ihnen zu schönem und Geschmeidigen Haar.
    [Bild: i6tfHoa3ooSEraFH63.png]
    Multithread ist offline

  14. #14 Zitieren
    Auserwählter
    Registriert seit
    Jul 2017
    Beiträge
    6.534
    Hm, ich hatte damals mit C++ angefangen. Dann einige Jahre nichts gemacht und kam dann irgendwie zu Java. Und es war eine Wohltat. Mir hat damals die Pointergeschichte überhaupt keinen Spaß gemacht. Man musste aufpassen wie ein Luchs. Ok, aufpassen muss man generell und Fehler sind grundsätzlich unerwünscht, aber für mich konnte ich sagen, das es viel Zeit sparte. Die Umstellung von C auf Java war recht einfach. Java bietet tolle Bibliotheken und man kann sich als Freizeitprogrammierer viel mehr auf das Programmieren konzentrieren.

    Von der Struktur her sehe ich das so wie Thoronador. Gute Struktur ist abhängig vom Programmierer. Auch in Java kann man so schreiben, dass man schon nach zwei Stunden nicht mehr weiß, was der Code da eigentlich machen soll. Und auch in Basic kann man so schreiben, dass man noch Jahre später recht schnell wieder reinkommt.
    Stiller Leser ist offline

  15. #15 Zitieren

    Batmanistrator
    Avatar von Thoronador
    Registriert seit
    Jul 2005
    Ort
    Morrowind, Vvardenfell-Distrikt
    Beiträge
    20.405
    Zitat Zitat von Progrinator Beitrag anzeigen
    @ Thoronador aber wenn man sein Code ordenlich aufzieht, dann sollte man nicht in die Gefahrlaufen, das Speicherlecks auftreten.
    Hehe, einfacher gesagt als getan. Natürlich gibt es in C/C++ keine Speicherlecks, und in Java gibt es keine NullPointerException und keinen OutOfMemoryError, wenn man den Code richtig aufzieht. Aber das ist bei größeren Anwendungen nicht unbedingt trivial. Doch aus der Erfahrung weiß man, dass beispielsweise RAII oder SmartPointer in C++ in dieser Hinsicht besser funktionieren als "nackte" Pointer mit new und delete, weil bei letzteren die Chance größer ist, dass sich Fehler im Speichermanagement einschleichen. Daher fängt man in der Regel in modernem C++ gar nicht mehr mit new/delete an und vermeidet es nach Möglichkeit.

    Zitat Zitat von Progrinator Beitrag anzeigen
    Was ich mich halt frage, gelten die Sachen die du schreibst auch für sehr Performance orientiertes Programmieren.
    Das kommt darauf an.TM
    Bei Performance kommt es aus meiner Sicht erstmal darauf an, dass man auch gute (sprich: passende und effiziente) Algorithmen nutzt. Oft ergeben sich auch aus Kenntnis der Anwendungsdomäne ein paar triviale Optimierungsmöglichkeiten. Wenn man beispielsweise in einem Container nach einem bestimmten Wert sucht, dann ist der Aufwand dafür im Allgemeinen linear in der Anzahl der Einträge - O(n). Weiß man aber, dass der Container immer aufsteigend sortiert ist, kann man statt linearer Suche einfach Binärsuche nutzen und ist damit beim deutlich geringeren Aufwand von O(log n) - logarithmisch in der Anzahl der Einträge. Hinzu kommt, dass moderne C++-Compiler sehr gut im Optimieren des erzeugten Codes sind, sodass man aus meiner Sicht eigentlich meistens auf einem hohen Abstraktionslevel bleiben kann, ohne dadurch an Performance einzubüßen. (Gutes Beispiel ist die Date-Bibliothek von Howard Hinnant, die nette Syntax und Funktionen für Datumsangaben mitbringt, aber kompiliert identischen Assemblycode zu low-level C erzeugt. Wird auch in dem Vortrag gezeigt, so irgendwo ab Minute 29 herum.)
    Am Schluss gilt aber auch hier wie bei allen performancekritischen Fällen: Messen! Und zwar mehrmals und nicht nur einen einzigen Programmdurchlauf. Nur das schafft Gewissheit.

    Zitat Zitat von Stiller Leser Beitrag anzeigen
    Hm, ich hatte damals mit C++ angefangen. Dann einige Jahre nichts gemacht und kam dann irgendwie zu Java. Und es war eine Wohltat. Mir hat damals die Pointergeschichte überhaupt keinen Spaß gemacht. Man musste aufpassen wie ein Luchs. Ok, aufpassen muss man generell und Fehler sind grundsätzlich unerwünscht, aber für mich konnte ich sagen, das es viel Zeit sparte. Die Umstellung von C auf Java war recht einfach. Java bietet tolle Bibliotheken und man kann sich als Freizeitprogrammierer viel mehr auf das Programmieren konzentrieren.
    Ich glaube, hier werden zwei Sachen miteinander vermischt oder vielleicht gar verwechselt. C ist nochmal anders als C++. (C würde ich spätestens seit C++11/C++14/C++17 auch niemandem mehr empfehlen, wenn auf der gleichen Plattform auch ein C++-Compiler verfügbar ist.) C und Java zu vergleichen ist ein bisschen wie Äpfel und Birnen. In C gibt es beispielsweise noch gar kein OOP und Pointer sind dort in vielen Fällen nicht die Ausnahme sondern eher die Norm. C++ und Java kann man hingegen schon vergleichen. Mit C++ kann man schön(er als in C) objektorientiert programmieren und von dem Pointergedöns kommt man dort auch weg. Manche Einstiegskurse zu C++ fangen quasi auch mit C an und hängen dann zum Schluss nur noch die C++-Sachen dran, weil die Person, die den Kurs leitet, früher in C programmiert hat und dafür einen Kurs hatte, und für den C++-Kurs einfach die Folien vom C-Kurs genommen und dann noch etwas C++ hinten drangehängt hat. Das ist aber grundsätzlich falsch und macht es nur schwieriger für Leute, die C++ und nicht C lernen wollen.

    Kurz gesagt: Pointer machen auf Dauer wenig Spaß, aber zum Glück muss man die in C++ nicht (oder nur noch selten) einsetzen.

    Zitat Zitat von Multithread Beitrag anzeigen
    Auch in C# kannst du selber für eine 'Gatrbage Collection' sorgen, das macht aber wenig sinn, da der GC ziemlich gut ist, in dem was er macht.
    Ich halte es da mit Bjarne Stroustrup: "C++ is my favourite garbage-collected language, because it generates so little garbage."
    Thoronador ist offline

  16. #16 Zitieren
    Deus Avatar von FlashX
    Registriert seit
    Oct 2007
    Ort
    R'lyeh
    Beiträge
    12.706
    Zitat Zitat von Thoronador Beitrag anzeigen
    Ich glaube, hier werden zwei Sachen miteinander vermischt oder vielleicht gar verwechselt. C ist nochmal anders als C++. (C würde ich spätestens seit C++11/C++14/C++17 auch niemandem mehr empfehlen, wenn auf der gleichen Plattform auch ein C++-Compiler verfügbar ist.) C und Java zu vergleichen ist ein bisschen wie Äpfel und Birnen. In C gibt es beispielsweise noch gar kein OOP und Pointer sind dort in vielen Fällen nicht die Ausnahme sondern eher die Norm. C++ und Java kann man hingegen schon vergleichen. Mit C++ kann man schön(er als in C) objektorientiert programmieren und von dem Pointergedöns kommt man dort auch weg. Manche Einstiegskurse zu C++ fangen quasi auch mit C an und hängen dann zum Schluss nur noch die C++-Sachen dran, weil die Person, die den Kurs leitet, früher in C programmiert hat und dafür einen Kurs hatte, und für den C++-Kurs einfach die Folien vom C-Kurs genommen und dann noch etwas C++ hinten drangehängt hat. Das ist aber grundsätzlich falsch und macht es nur schwieriger für Leute, die C++ und nicht C lernen wollen.
    Interessanter Vortrag. Mir kommt es fast so vor, als hätte sich mein Dozent daran orientiert, als er damals die Erstsemestervorlesung (Einführung in die praktische Informatik) übernommen hatte.

    C-Arrays komplett übersprungen und stattdessen von Beginn an mit dem std::vector gearbeitet, Pointer (fast) komplett übersprungen und nur Referenzen und Iteratoren eingeführt, da letztere in manchen <algorithm>-Funktionen als Parameter übergeben werden müssen, außerdem Lambda-Funktionen (in Verbindung mit std::sort), gefolgt von OOP und Templates. Ganz zum Schluss hat er erst Vererbung angeschnitten und die war auch nicht mehr klausurrelevant - wenn ich mich recht erinnere, mit der Begründung, dass Vererbung außer in der Bildbearbeitung (oder so ähnlich) kaum mehr eine praktische Rolle spiele und die Sache für Anfänger nur unnötig kompliziert mache. Nur zwischendurch haben wir einmal mit C-Strings gearbeitet, als es darum ging, einen String mit atoi() in einen Integer umzuwandeln - an dieser Stelle war aber auch der entsprechende Code in der Aufgabenstellung gegeben.

    Lustigerweise hatten wir parallel den Blockkurs "Programmierkurs C++" bei einem anderen Dozenten, in dem der Fokus aber auf C-Arrays, Pointern, der Implementierung einer verketteten Liste und erst zum Schluss auf OOP inkl. Vererbung lag.
    ~ That is not dead which can eternal lie
    ~ And with strange aeons even death may die

    We shall swim out to that brooding reef in the sea and dive down through black abysses to Cyclopean and many-columned Y'ha-nthlei,
    and in that lair of the Deep Ones we shall dwell amidst wonder and glory for ever.
    FlashX ist offline Geändert von FlashX (13.02.2019 um 23:53 Uhr)

  17. #17 Zitieren

    Batmanistrator
    Avatar von Thoronador
    Registriert seit
    Jul 2005
    Ort
    Morrowind, Vvardenfell-Distrikt
    Beiträge
    20.405
    Zitat Zitat von FlashX Beitrag anzeigen
    Lustigerweise hatten wir parallel den Blockkurs "Programmierkurs C++" bei einem anderen Dozenten, in dem der Fokus aber auf C-Arrays, Pointern, der Implementierung einer verketteten Liste und erst zum Schluss auf OOP inkl. Vererbung lag.
    Das ist halt der typische Kursinhalt von Leuten, die früher C (ohne ++) unterrichtet haben und jetzt plötzlich C++ machen wollen/sollen/müssen. Pointer werden dann meist genutzt, um Listen implementieren zu können - das ist halt das klassische Beispiel. Bei solchen "C++-Kursen" (die eigentlich nur C-Kurse mit etwas C++-Syntax sind) kann man auch verstehen, dass manche Leute ein schlechtes Bild von der Sprache haben. Dabei gib es doch schon std::list - eine generische Implementierung einer Liste. Eine verkettete Liste muss man nicht neu schreiben, das kommt schon mit der Standardbibliothek von C++ mit. Aber abgesehen davon sollte man ja ohnehin std::vector nutzen. ("If you need a collection class, use vector. If you are special, and performance matters to you, and vector is not going to work for you - no problem, I totally get it. Use vector." - Kate Gregory)
    Thoronador ist offline

  18. #18 Zitieren
    Deus Avatar von FlashX
    Registriert seit
    Oct 2007
    Ort
    R'lyeh
    Beiträge
    12.706
    Ich muss allerdings dazu sagen, dass die Implementierung einer verketten Liste meiner Meinung nach etwas ist, das man mal getan haben sollte - egal ob nun in C oder C++. Sie hilft ungemein beim Verständnis von Pointern und nichtzusammenhängendem Speicher, und wird damit spätestens bei Dateisystemen, Datenbankarchitekturen und Seitenersetzungsalgorithmen wichtig. Zumindest sofern man Informatik studiert und sich somit mit diesen Dingen auseinandersetzen muss
    ~ That is not dead which can eternal lie
    ~ And with strange aeons even death may die

    We shall swim out to that brooding reef in the sea and dive down through black abysses to Cyclopean and many-columned Y'ha-nthlei,
    and in that lair of the Deep Ones we shall dwell amidst wonder and glory for ever.
    FlashX ist offline

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •