Top-Fehler von C++-Anfängern: Fortgeschrittenes Niveau

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: Wenn C++ aufhört, "nur eine Sprache" zu sein



Sie haben bereits ein Dutzend Konsolenprogramme geschrieben, gelernt, std::vector zu verwenden, und sich sogar mit Templates vertraut gemacht. Aber C++ ist eine Sprache, die eine oberflächliche Herangehensweise niemals verzeiht. Ein Anfänger-Entwickler erreicht genau dann die nächste Stufe, wenn er auf undefiniertes Verhalten (UB) stößt und zu verstehen beginnt, dass der Compiler kein freundlicher Freund, sondern ein strenger Vertragspartner ist.



In diesem Artikel werden wir nicht über banale Fehler wie ein vergessenes ; oder die Verwechslung von = und == sprechen. Wir werden über Fallstricke sprechen, die auf diejenigen warten, die die Syntax bereits kennen, aber die Philosophie der Sprache noch nicht verinnerlicht haben. Diese Fehler sind die Ursache für 90% der schwer zu findenden Bugs in industriellem Code.



1. Ignorieren der Rule of Five und Rule of Zero



Problem: Implizit generierte spezielle Member-Funktionen



Viele Entwickler, die von Java oder Python umgestiegen sind, glauben, dass der Compiler das Kopieren und Verschieben von Objekten "schon schön machen" wird. Das ist ein gefährlicher Irrglaube.



Betrachten wir eine Klasse mit einer dynamischen Ressource:



class Buffer {public:    Buffer(size_t size) : data(new char[size]), size(size) {}    ~Buffer() { delete[] data; }        // Alles in Ordnung? Nein! Es gibt keinen Kopierkonstruktor und Zuweisungsoperator!private:    char* data;    size_t size;};

void process() { Buffer a(100); Buffer b = a; // Flache Kopie! Zwei Zeiger auf denselben Speicher.} // Doppelte Freigabe — UB!


Die Rule of Five besagt: Wenn Sie mindestens eine der fünf speziellen Methoden (Destruktor, Kopierkonstruktor, Kopierzuweisungsoperator, Verschiebekonstruktor, Verschiebezuweisungsoperator) definieren, müssen Sie alle definieren.



Lösung: Verwenden Sie std::unique_ptr oder std::vector zur Ressourcenverwaltung. Dies ist der Ansatz der Rule of Zero: Wenn Ihre Klasse Ressourcen nicht direkt verwaltet, generiert der Compiler selbst korrekte spezielle Funktionen.



class Buffer {public:    Buffer(size_t size) : data(std::make_unique<char[]>(size)), size(size) {}    // Rule of Zero — Destruktor, Kopieren und Verschieben funktionieren korrekt!private:    std::unique_ptr<char[]> data;    size_t size;};


2. Falsche Verwendung der Move-Semantik



Problem: Move macht ein Objekt nicht automatisch "leer"



Einer der tückischsten Fehler ist der Glaube, dass das Quellobjekt nach std::move "sicher" zu verwenden ist. Tatsächlich ist std::move nur eine Umwandlung in einen Rvalue-Referenz. Der Zustand des verschobenen Objekts hängt von der Implementierung ab.



std::string a = "Hallo, Welt!";std::string b = std::move(a);std::cout << a;  // Technisch gesehen — UB? Nein, aber der Inhalt von a ist undefiniert!// Kann ein leerer String sein, oder "Hallo, Welt!"


Der Standard garantiert nur, dass sich das verschobene Objekt in einem gültigen, aber undefinierten Zustand befindet. Sie können a.clear() oder a = "neuer Wert" aufrufen, sollten sich aber nicht auf seinen Inhalt verlassen.



Tipp: Setzen Sie das Objekt nach dem Verschieben entweder in einen bekannten Zustand zurück oder verwenden Sie es nicht mehr. Dokumentieren Sie für benutzerdefinierte Typen immer die Nachbedingungen des Verschiebekonstruktors.



3. Speicherlecks durch rohe Zeiger und Ausnahmen



Problem: Ausnahmen "zerreißen" die Kette der Ressourcenfreigabe



Sogar erfahrene Entwickler schreiben manchmal Code mit manueller Speicherverwaltung:



void process() {    int* ptr1 = new int(42);    int* ptr2 = new int(100);        // Wenn hier eine Ausnahme ausgelöst wird — Speicherleck von ptr1!    dangerous_function();        delete ptr2;    delete ptr1;}


In C++ gibt es kein finally

Blogs

Buchempfehlungen