How to Pass a C++ Interview: Top Advanced-Level Questions
\n\nAn interview for a mid-level or senior C++ developer position is not just a syntax check. Interviewers want to see a deep understanding of the language's internal workings, the ability to work with memory, templates, and multithreading. In this article, we have broken down the most common and difficult questions asked in advanced C++ interviews. Each question is accompanied by an explanation and code example.
\n\n1. Smart Pointers and RAII
\n\nThe question about smart pointers is a classic. You are expected not only to name std::unique_ptr, std::shared_ptr, and std::weak_ptr, but also to explain their internal structure and when to use which.
Typical question: What is the difference between unique_ptr and shared_ptr? How does the reference counter in shared_ptr work? Why is weak_ptr needed?
Answer: std::unique_ptr is exclusive ownership of a resource. It cannot be copied, only moved (move semantics). std::shared_ptr uses reference counting for shared ownership. When the counter drops to zero, the object is deleted. std::weak_ptr is an "observer" that does not increment the reference counter. It is used to prevent circular dependencies (e.g., in graphs or trees).
#include <memory>\n#include <iostream>\n\nstruct Resource {\n Resource() { std::cout << "Resource acquired\\n"; }\n ~Resource() { std::cout << "Resource released\\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; // Compilation error - copying is forbidden\n std::unique_ptr<Resource> ptr2 = std::move(ptr1); // Moving is allowed\n\n // shared_ptr\n std::shared_ptr<Resource> sptr1 = std::make_shared<Resource>();\n std::shared_ptr<Resource> sptr2 = sptr1; // Copying is allowed, counter = 2\n\n // weak_ptr\n std::weak_ptr<Resource> wptr = sptr1; // Counter is not incremented\n if (auto locked = wptr.lock()) {\n std::cout << "Resource is still alive\\n";\n }\n\n return 0;\n}\n\nAdditional question: How to implement your own SharedPtr? Here it is important to mention RAII (Resource Acquisition Is Initialization) — the principle where resource acquisition occurs in the constructor and release in the destructor.
2. Virtual Destructors and the Virtual Function Table (vtable)
\n\nThis question tests understanding of polymorphism and the structure of virtual functions in C++.
\n\nTypical question: Why must a base class with virtual functions necessarily have a virtual destructor? How does the vtable work?
\n\nAnswer: If the base class destructor is not virtual, then when deleting a derived class object through a pointer to the base class, only the base class destructor will be called. This will lead to resource leaks that the derived class allocated.
\n\nEach class that has at least one virtual function contains a static table (vtable). It stores pointers to the implementations of virtual functions. Each object of such a class has a hidden pointer (vptr) that points to its class's vtable. Calling a virtual function happens through double indirection: object → vptr → vtable → function. This adds a small overhead compared to a regular call.
\n\n#include <iostream>\n\nclass Base {\npublic:\n virtual void show() { std::cout << "Base\\n"; }\n virtual ~Base() = default; // Virtual destructor\n};\n\nclass Derived : public Base {\npublic:\n void show() override { std::cout << "Deriv