C++ vs C and Basics
1. Key differences between C and C++?
C++ adds: classes & objects, templates, exceptions, namespaces, references, function overloading, the STL, RAII, smart pointers, and lambda expressions. C++ is mostly a superset of C (with some incompatibilities).
2. Pass by value vs reference vs pointer?
void byValue(int x); // copy; safe but slow for large types
void byRef(int& x); // alias; no copy; can modify caller's var
void byConstRef(const T& x); // no copy; read-only — modern default for large types
void byPointer(int* x); // explicit; nullable
3. Reference vs pointer?
| Reference | Pointer | |
|---|---|---|
| Nullable | ❌ | ✅ |
| Reseatable | ❌ | ✅ |
| Syntax | x.field | p->field |
| Init required | ✅ at decl | ❌ |
RAII and Memory
4. What is RAII?
Resource Acquisition Is Initialization. Resources (memory, file handles, locks) are tied to object lifetime — acquired in the constructor, released in the destructor. Eliminates entire categories of leaks.
5. unique_ptr vs shared_ptr vs weak_ptr?
unique_ptr<T>— sole owner; non-copyable, movable. Default choice.shared_ptr<T>— reference-counted shared ownership. Use only when ownership is genuinely shared.weak_ptr<T>— non-owning observer of ashared_ptr. Used to break reference cycles.
6. When should you use raw pointers in modern C++?
- Non-owning references to objects whose lifetime is managed elsewhere.
- Inside library internals where ownership is clear.
- Almost never for owning. Use
unique_ptr/shared_ptr/make_uniqueinstead.
Move Semantics
7. What is std::move?
A cast that converts an lvalue to an rvalue, enabling move construction / move assignment to steal resources instead of copy.
std::vector<int> v1 = {1,2,3};
std::vector<int> v2 = std::move(v1); // O(1) move, no element copy
// v1 is now in a valid-but-unspecified state — assign to it before reading
8. Rule of zero / three / five?
- Rule of zero — let the compiler generate all special members. Prefer this. Use RAII members so you don't need any custom ones.
- Rule of three — if you write one of {copy ctor, copy assign, dtor}, write all three.
- Rule of five — same, but with move ctor + move assign too in modern C++.
9. std::forward vs std::move?
Both are casts. std::move always casts to rvalue. std::forward<T> preserves the value category (lvalue / rvalue) of its template argument — used in perfect forwarding inside templates.
STL
10. vector vs array vs deque?
std::vector<T>— dynamic array; contiguous; O(1) random access; O(1) amortised push_back; O(n) front insert.std::array<T, N>— fixed-size, stack-allocated.std::deque<T>— double-ended queue; O(1) push/pop at both ends; not contiguous.
11. map vs unordered_map?
std::map | std::unordered_map | |
|---|---|---|
| Backing | Red-black tree | Hash table |
| Ordered keys | ✅ | ❌ |
find | O(log n) | O(1) average |
| Worst case | O(log n) | O(n) |
| Memory | Lower | Higher |
12. emplace_back vs push_back?
push_back(T) copies/moves an existing object. emplace_back(args...) constructs the object in place inside the container, avoiding a temporary. Prefer emplace_back when constructing.
Templates
13. Function template vs class template?
- Function template —
template<typename T> T add(T a, T b) { return a + b; }. - Class template —
template<typename T> class Stack { … }.
14. What is template specialisation?
A specific implementation for a particular type:
template<typename T> struct Trait { static const bool isPointer = false; };
template<typename T> struct Trait<T*> { static const bool isPointer = true; };
15. auto in C++ — when and why?
autolets the compiler deduce the type. Reduces verbosity, especially with iterators, lambdas, templates.- Use it when the type is obvious from context or genuinely complicated. Don't use it when it hides important information.
Modern C++ (17 / 20 / 23)
16. Range-based for, structured bindings?
for (const auto& [key, value] : myMap) { // C++17 structured binding
std::cout << key << " => " << value;
}
17. std::optional vs std::variant vs std::any?
std::optional<T>— T or nothing. Replaces "magic value" sentinels.std::variant<A, B, C>— exactly one of a fixed set of types (tagged union).std::any— any type at all (use sparingly).
18. C++20 highlights?
- Modules — replace headers (gradually adopted).
- Concepts — constrain templates with readable predicates.
- Coroutines —
co_await,co_return. - Ranges — composable lazy views.
std::format— Python-style formatting.
19. C++23 highlights?
std::print— finally a built-inprint().- Deducing
this— explicit object parameter. std::expected<T, E>— error handling without exceptions.- Multidimensional
operator[].
Concurrency
20. std::thread vs std::async vs std::jthread?
std::thread— manual; you mustjoin()ordetach()before destruction.std::async— returns afuture; runtime decides if launched in a new thread or deferred.std::jthread(C++20) — auto-joining thread + built-in cancellation.
21. Race condition vs deadlock?
- Race condition — multiple threads access shared data without synchronisation, result depends on timing.
- Deadlock — two or more threads each hold a lock the other needs and wait forever. Avoid with consistent lock ordering or
std::scoped_lock(acquires multiple atomically).
