Modern C++ and Interview Prep · Lesson 33 of 33
C++ Interview Questions and STL Cheat Sheet
C++ interviews test three things: whether you can pick the right STL tool and know its cost, whether you understand what C++ does under the hood (objects, memory, polymorphism), and whether you write modern, safe code. This lesson gathers the essentials into a cheat sheet, the questions asked most often, and a few output puzzles with explanations.
In this lesson
- STL complexity cheat sheet
- Core language and OOP questions
- Memory and modern C++ questions
- Output puzzles explained
STL cheat sheet
| Container | Access | Insert / erase | Search | Notes |
|---|---|---|---|---|
vector | O(1) | O(1)* back, O(n) middle | O(n), O(log n) if sorted | the default |
deque | O(1) | O(1) both ends | O(n) | queue/stack backbone |
list | – | O(1) at an iterator | O(n) | stable iterators |
set / map | – | O(log n) | O(log n) | sorted; lower_bound |
unordered_set / map | – | O(1) avg | O(1) avg | no order; O(n) worst |
priority_queue | top O(1) | O(log n) | – | max heap by default |
stack / queue | top/front O(1) | O(1) | – | adapters over deque |
* amortised. Algorithms: sort O(n log n), stable_sort O(n log n), nth_element O(n) avg, lower_bound O(log n) on random-access ranges, unique/reverse/accumulate O(n).
Core language and OOP
| Question | Key points |
|---|---|
| Pointer vs reference | references can't be null or re-bound and need no *; pointers can be null, re-pointed and do arithmetic |
| Pass by value / reference / const reference | small types by value, large inputs by const&, modified outputs by & |
| struct vs class | only the default access differs (public vs private) |
| Function overloading vs overriding | overloading: same name, different parameters, compile time; overriding: virtual function redefined in a derived class, run time |
| How do virtual functions work? | each polymorphic class has a vtable; each object a vptr; calls go through it at run time |
| Why a virtual destructor? | so deleting a derived object through a base pointer destroys the derived part |
| Abstract class | has at least one pure virtual function (= 0); can't be instantiated |
| Object slicing | copying a derived object into a base value loses the derived part – use pointers/references |
| const member function | doesn't modify the object; callable on const objects |
| static member | one copy shared by all objects of the class |
Memory and modern C++
| Question | Key points |
|---|---|
| Stack vs heap | automatic locals vs dynamic memory; heap lifetime controlled by owners |
| new/delete vs malloc/free | new calls constructors and is type-safe; delete calls destructors; never mix them |
| What is RAII? | resources owned by objects; released in destructors – no leaks even with exceptions |
| unique_ptr vs shared_ptr vs weak_ptr | single owner / reference-counted owners / non-owning observer that breaks cycles |
| Move semantics | transfer resources from temporaries instead of copying; std::move is just a cast |
| Rule of zero / three / five | let members manage resources; if you write one special function, you probably need all |
| Shallow vs deep copy | copying a pointer vs copying what it points to |
| What is a dangling pointer? | points to memory that was freed or went out of scope |
| Templates vs virtual functions | compile-time polymorphism (fast, code per type) vs run-time polymorphism (one code path, vtable) |
| What are concepts? | named compile-time requirements on template parameters (C++20) |
Output puzzles
#include <iostream>
#include <string>
#include <vector>
struct Base {
virtual ~Base() = default;
virtual std::string who() const { return "Base"; }
std::string plain() const { return "Base::plain"; }
};
struct Derived : Base {
std::string who() const override { return "Derived"; }
std::string plain() const { return "Derived::plain"; } // hides, doesn't override
};
void by_value(Base b) { std::cout << "by value: " << b.who() << '\n'; }
void by_ref(const Base& b) { std::cout << "by reference: " << b.who() << '\n'; }
int main() {
Derived d;
Base& ref = d;
std::cout << "1) " << ref.who() << ", " << ref.plain() << '\n'; // virtual vs non-virtual
by_value(d); // 2) slicing
by_ref(d);
std::vector<int> v{1, 2, 3};
std::vector<int> w = v; // deep copy
w[0] = 100;
std::cout << "3) " << v[0] << ' ' << w[0] << '\n';
int x = 10;
auto by_val = [x] { return x; };
auto by_rf = [&x] { return x; };
x = 20;
std::cout << "4) " << by_val() << ' ' << by_rf() << '\n'; // capture timing
std::string s = "abc";
std::cout << "5) " << sizeof(s.c_str()[0]) << ' ' << s.size() << ' ' << (s + "def").size() << '\n';
return 0;
}
1) Derived, Base::plain by value: Base by reference: Derived 3) 1 100 4) 10 20 5) 1 3 6
| # | Why |
|---|---|
| 1 | who is virtual, so the Derived version runs through a Base reference; plain isn't, so the static type (Base) decides |
| 2 | passing by value copies only the Base part (slicing), so Base::who runs; by reference keeps the real type |
| 3 | copying a vector copies its elements – they're independent |
| 4 | [x] copied 10 when the lambda was created; [&x] reads the current value 20 |
| 5 | a char is 1 byte; "abc" has 3 characters; concatenation gives 6 |
How to stand out
- State the complexity of every solution, and why you chose that container.
- Write modern C++: vector over raw arrays, smart pointers over new/delete, const& parameters, range-for.
- Mention edge cases: empty input, overflow (use long long), duplicates.
- Know when behaviour is undefined, and say so instead of guessing an output.
Keep practising
- Arrays, linked lists, stacks and queues
- Trees and binary search trees
- Time and space complexity
- Recursion and backtracking
- Array and string coding questions
- DSA tricky questions and edge cases
- Daily Code Challenge – keep a streak going
Summary
- Know every container's costs and when to use it.
- Be ready to explain virtual dispatch, slicing, RAII, smart pointers and move semantics.
- Write modern, safe C++ and always discuss complexity and edge cases.
Finished this lesson?
Mark it complete to track your progress. You have reached the end of this track — well done!