So bestehst du das C++-Vorstellungsgespräch: Top-Fragen für Fortgeschrittene

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

So bestehst du das C++-Vorstellungsgespräch: Top-Fragen für Fortgeschrittene

\n\n

Ein Vorstellungsgespräch für eine Position als C++-Entwickler auf mittlerem und höherem Niveau ist nicht nur eine Überprüfung der Syntax. Interviewer möchten ein tiefes Verständnis der inneren Funktionsweise der Sprache, die Fähigkeit, mit Speicher, Templates und Multithreading umzugehen, sehen. In diesem Artikel haben wir die häufigsten und schwierigsten Fragen zusammengestellt, die in fortgeschrittenen C++-Vorstellungsgesprächen gestellt werden. Jede Frage wird mit einer Erklärung und einem Codebeispiel begleitet.

\n\n

1. Smart Pointer und RAII

\n\n

Die Frage nach Smart Pointern ist ein Klassiker. Es wird erwartet, dass du nicht nur std::unique_ptr, std::shared_ptr und std::weak_ptr nennst, sondern auch ihre innere Funktionsweise erklärst und wann welcher verwendet wird.

\n\n

Typische Frage: Was ist der Unterschied zwischen unique_ptr und shared_ptr? Wie funktioniert der Referenzzähler in shared_ptr? Wozu braucht man weak_ptr?

\n\n

Antwort: std::unique_ptr ist exklusiver Besitz einer Ressource. Er kann nicht kopiert, sondern nur verschoben werden (Move-Semantik). std::shared_ptr verwendet Referenzzählung (Reference Counting) für geteilten Besitz. Wenn der Zähler auf Null fällt, wird das Objekt gelöscht. std::weak_ptr ist ein "Beobachter", der den Referenzzähler nicht erhöht. Er wird verwendet, um zyklische Abhängigkeiten zu verhindern (z. B. in Graphen oder Bäumen).

\n\n
#include <memory>\n#include <iostream>\n\nstruct Resource {\n    Resource() { std::cout << "Resource erworben\\n"; }\n    ~Resource() { std::cout << "Resource freigegeben\\n"; }\n};\n\nint main() {\n    // unique_ptr\n    std::unique_ptr<Resource> ptr1 = std::make_unique<Resource>();\n    // std::unique_ptr<Resource> ptr2 = ptr1; // Kompilierungsfehler - Kopieren verboten\n    std::unique_ptr<Resource> ptr2 = std::move(ptr1); // Verschieben erlaubt\n\n    // shared_ptr\n    std::shared_ptr<Resource> sptr1 = std::make_shared<Resource>();\n    std::shared_ptr<Resource> sptr2 = sptr1; // Kopieren erlaubt, Zähler = 2\n\n    // weak_ptr\n    std::weak_ptr<Resource> wptr = sptr1; // Zähler wird nicht erhöht\n    if (auto locked = wptr.lock()) {\n        std::cout << "Resource ist noch lebendig\\n";\n    }\n\n    return 0;\n}
\n\n

Zusatzfrage: Wie implementiert man einen eigenen SharedPtr? Hier ist es wichtig, RAII (Resource Acquisition Is Initialization) zu erwähnen – das Prinzip, bei dem die Ressourcenakquise im Konstruktor und die Freigabe im Destruktor erfolgt.

\n\n

2. Virtuelle Destruktoren und die Tabelle der virtuellen Funktionen (vtable)

\n\n

Diese Frage überprüft das Verständnis von Polymorphie und der Funktionsweise virtueller Funktionen in C++.

\n\n

Typische Frage: Warum muss eine Basisklasse mit virtuellen Funktionen zwingend einen virtuellen Destruktor haben? Wie funktioniert die vtable?

\n\n

Antwort: Wenn der Destruktor der Basisklasse nicht virtuell ist, wird beim Löschen eines Objekts einer abgeleiteten Klasse über einen Zeiger auf die Basisklasse nur der Destruktor der Basisklasse aufgerufen. Dies führt zu Speicherlecks der Ressourcen, die die abgeleitete Klasse allokiert hat.

\n\n

Jede Klasse, die mindestens eine virtuelle Funktion hat, enthält eine statische Tabelle (vtable). In ihr werden Zeiger auf die Implementierungen der virtuellen Funktionen gespeichert. Jedes Objekt einer solchen Klasse hat einen versteckten Zeiger (vptr), der auf die vtable seiner Klasse zeigt. Der Aufruf einer virtuellen Funktion erfolgt über eine doppelte Indirektion: Objekt → vptr → vtable → Funktion. Dies fügt im Vergleich zu einem normalen Aufruf einen kleinen Overhead hinzu.

\n\n
#include <iostream>\n\nclass Base {\npublic:\n    virtual void show() { std::cout << "Base\\n"; }\n    virtual ~Base() = default; // Virtueller Destruktor\n};\n\nclass Derived : public Base {\npublic:\n    void show() override { std::cout << "Deriv                

Blogs

Buchempfehlungen