💡 TL;DR:The most frequently asked C++ interview questions with concise answers and deep dives: const, static, virtual functions, smart pointers, STL internals, move semantics, multithreading and more.
Last updated:2026-11-10
C++ Interview Questions and Answers¶
A curated list of the most frequently asked C++ interview questions, each with a concise answer you can give in an interview and a link to a deep-dive article with code, internals, and pitfalls. It covers language fundamentals, OOP, memory management, STL internals, modern C++ (11/17/20), templates, and concurrency — and ends with the C-language questions C++ candidates are still expected to answer.
Use it as a checklist before an interview, or as a study map: every answer links to the full treatment in the C++那些事 (Stories About C++) guide.
1. Language Fundamentals¶
What does const mean in C++? What are const pointers vs pointers to const?¶
const promises immutability at compile time. const int* p (pointer to const) forbids writing through p but lets p re-point; int* const p (const pointer) forbids re-pointing but allows writing; const int* const p forbids both. Also distinguish compile-time constants from const in declarations (which have external linkage in C++ and internal in C), and where constexpr is the better tool.
→ Deep dive: C++ const Constants & Qualifiers and The const Family in C++
What is static in C++? List all its uses.¶
Four distinct meanings: (1) file-scope internal linkage for globals/functions; (2) function-local variables with a single shared instance initialized once; (3) per-class member variables shared by all instances; (4) per-class member functions callable without an object. Interviewers usually follow up with initialization order and thread-safety of function-local statics (guaranteed since C++11).
→ Deep dive: C++ static Members & Lifetime
struct vs class in C++?¶
Only two differences: default access (public for struct, private for class) and default inheritance mode. Everything else — constructors, virtual functions, templates — is identical for both. Choosing between them is convention, not mechanics.
→ Deep dive: struct vs class
What is the difference between pointers and references?¶
A reference must be bound at initialization and can never be null or reseated; a pointer can be null, reassigned, and arithmetic applies. References enable operator overloading with value-like syntax. Prefer references for "always bound" parameters, pointers when "no object" is a valid state.
→ Deep dive: C++ Pointers & References
When does the compiler actually inline a function?¶
inline is a hint, not a command: the compiler decides by cost model, and it mainly solves the One-Definition-Rule for multi-TU definitions. Member functions defined in-class are implicitly inline. Inlining can also happen without the keyword (link-time optimization).
→ Deep dive: C++ inline Functions
What does sizeof return for common types, and what does it not measure?¶
sizeof yields the byte size of the type representation, including padding — it does not measure heap allocations behind a pointer (sizeof(std::string) is the size of the string object, not the characters). Watch alignment rules and why sizeof on a struct with bit fields surprises people.
→ Deep dive: The C++ sizeof Operator and C++ Bit Fields
Why does volatile NOT make code thread-safe?¶
volatile only forbids the compiler from caching/eliminating accesses — it inserts no memory barriers and creates no atomicity or happens-before relationships. For inter-thread communication use std::atomic and mutexes; volatile is for memory-mapped I/O.
→ Deep dive: The C++ volatile Keyword
What is the explicit keyword for?¶
It stops single-argument constructors (and conversion operators, since C++11) from creating implicit conversions. Classic example: preventing MyVec v = 10; from compiling. Essential on any single-arg constructor whose argument is not semantically the value of the type.
→ Deep dive: The C++ explicit Keyword
union, macro pitfalls, and extern linkage — still asked?¶
Yes, especially in systems roles: unions for type-punning-free memory reuse (now std::variant in modern code), macros' lack of scope/type-checking (prefer constexpr/inline functions), and extern "C" disabling name mangling for C interop.
→ Deep dive: C++ union · C++ Macros & Conditional Compilation · C++ extern & Linkage
2. OOP and Polymorphism¶
How do virtual functions work? What are vptr and vtable?¶
Each polymorphic class gets a compiler-generated vtable of function pointers; each object carries a hidden vptr to its dynamic type's vtable. A virtual call loads the vptr, indexes the slot, and indirectly calls — that is the runtime cost (one indirection, not "slow"). Constructors can't be virtual; destructors of base classes must be.
→ Deep dive: C++ virtual Functions and C++ vptr & vtable
Pure virtual functions and abstract classes — what can't they do?¶
A pure virtual (= 0) marks a function with no default implementation; the class becomes abstract and can't be instantiated. Pure-virtual-with-body exists (subclasses may call it explicitly). Abstract classes define interfaces; the destructor question (protected non-virtual vs public virtual) is a common follow-up.
→ Deep dive: Pure Virtual Functions & Abstract Classes
Can you implement polymorphism in C?¶
Yes — hand-rolled vtables: a struct of function pointers embedded as the first member, with subclasses sharing the prefix layout. Understanding this demystifies what C++ generates for you.
→ Deep dive: C-Style Polymorphism in C++
What is this and when is it typed differently?¶
this is a pointer to the current object; in a const member function it becomes const T*. In constructors/destructors its dynamic type is the class under construction — which is why virtual calls don't dispatch to derived overrides there.
→ Deep dive: The C++ this Pointer
3. Memory Management¶
new/delete vs malloc/free?¶
new calls constructors, returns a typed pointer, and throws on failure (new(std::nothrow) returns null); malloc only allocates raw bytes. Mismatching them (free on new'd memory) is UB. Placement new, operator new overloading, and alignment (C++17 std::aligned_alloc / alignas) are frequent follow-ups.
→ Deep dive: C++ Memory & Debugging series
How do you pass smart pointers as parameters?¶
By value only when transferring/borrowing ownership semantics demand it; pass unique_ptr<T>&& to take ownership, raw pointer or reference just to use the object. Taking shared_ptr by value copies a control block for no reason. This is the single most practical smart-pointer interview question.
→ Deep dive: Smart Pointers as Parameters
How would you hunt down a memory leak in production?¶
Reproduce under a tool: Valgrind memcheck for small cases, Massif/heaptrack for growth analysis, ASan (-fsanitize=address) for CI, and __gnu_cxx::freeres/custom new-hooks for targeted builds. Match every allocation with a deallocation strategy: RAII first.
→ Deep dive: Hunting Memory Leaks in Practice
What is EBO and why do empty classes still take 1 byte?¶
Distinct objects need distinct addresses, so sizeof(empty) is at least 1 — which pads base-class subobjects and members. Empty Base Optimization makes an empty base occupy zero space; C++20 [[no_unique_address]] does the same for members. This is how std::tuple avoids bloating.
→ Deep dive: STL EBO: Empty Base Optimization
4. STL Internals¶
How does std::vector grow, and when do iterators invalidate?¶
Geometric growth (×1.5–2): when capacity is exceeded, a new buffer is allocated, elements are moved/copied, and the old is freed — invalidating all iterators/pointers. push_back amortizes O(1). reserve avoids repeated reallocation; resize changes size, reserve only capacity.
→ Deep dive: STL Source-Code Analysis: vector and vector resize vs reverse
map vs unordered_map — implementation and choice?¶
map is a red-black tree: ordered iteration, O(log n) operations, iterator stability. unordered_map is a bucket-array hash table: O(1) average, rehashing invalidates iterators but not pointers, and requires a hash + equality. Choose by whether you need ordering; know both worst cases.
→ Deep dive: STL Red-Black Tree · STL map & multimap · STL Source-Code Analysis: unordered_map
How is a hashtable implemented in the libstdc++ STL?¶
Prime-count bucket array with chaining; single-element buckets store nodes, and since C++11 unordered_map keeps a singly-linked list of all elements. Know rehash policy (load_factor, max_load_factor) and why your custom key type needs std::hash specialization.
→ Deep dive: STL hashtable and Hand-Writing a Hash Table
What are traits? Why does the STL need them?¶
Traits are compile-time metadata about types (iterator_traits<T>::value_type) so generic code can adapt: the same std::copy dispatches on random-access vs forward iterators for memmove fast paths. This is the gateway question to template metaprogramming.
→ Deep dive: STL traits Techniques
Which iterators does deque use, and why is it segmented?¶
deque chunks storage into fixed-size blocks with a map of block pointers, giving O(1) push at both ends with a random-access (but non-contiguous) memory model. Its iterator does two-level dereference — a classic "implement it on a whiteboard" question.
→ Deep dive: STL Source-Code Analysis: deque
5. Modern C++ (11/14/17/20)¶
What does std::move actually do?¶
Nothing at runtime: it's a cast to an rvalue reference that enables move constructor/assignment selection. The source is left valid-but-unspecified. Move semantics transfer resources (buffers, handles) instead of copying — the heart of modern C++ performance.
→ Deep dive: std::move: How It Works
auto and decltype — rules and pitfalls?¶
auto drops references and top-level const by value-deduction rules; decltype(expr) gives the declared type without the auto decay. Common trap: auto in range-for over a temporary container. decltype(auto) preserves the exact type.
→ Deep dive: C++ decltype
What changed with lambdas in modern C++?¶
Capture-by-value/reference with [], mutable, generic lambdas (C++14), constexpr lambdas and template parameter lists (C++20). Know what a captureless lambda converts to (function pointer) and why capturing lambdas can't.
→ Deep dive: std::bind vs lambda and C++20 Lambdas (Part 1)
Why does std::string_view exist and how do you shoot yourself in the foot with it?¶
Non-owning borrow of characters: cheap to pass, no allocation — but dangling views (returning a view of a temporary string) and the "may not be null-terminated" rule are the traps. Pass by value; never store beyond the owner's lifetime.
→ Deep dive: C++17 std::string_view
std::variant vs union vs inheritance?¶
variant is a type-safe sum type with an index and value-by-alternative access (std::get_if, std::visit); unions are unchecked; virtual inheritance adds heap indirection but open extension. Use variant for closed sets of states — the visitor pattern question often follows.
→ Deep dive: C++17 std::variant
What do Concepts fix compared to SFINAE?¶
Concepts (requires) make template constraints first-class, produce readable error messages, and participate in overload resolution — replacing the purpose-built SFINAE machinery (std::enable_if, expression SFINAE) for most cases.
→ Deep dive: C++20 Concepts
6. Templates and Generic Code¶
What is the two-phase lookup and the typename disambiguator?¶
Dependent names are looked up at instantiation; typename tells the parser that a dependent qualified name is a type (and template that it's a template) — required before C++20 relaxed some cases in function bodies.
→ Deep dive: STL Source-Code Analysis: typename and Template Disambiguation
Variadic templates: how do you process a parameter pack?¶
Recursion (base case + pack expansion) or fold expressions (C++17): (f(args), ...). Perfect forwarding with Args&&... + std::forward — the foundation of std::make_unique and emplace APIs.
→ Deep dive: Variadic Templates
7. Concurrency¶
std::thread vs std::jthread — why was the latter added?¶
jthread joins in its destructor (no terminate-on-destruction), and supports cooperative cancellation via std::stop_token. It fixes std::thread's two sharpest edges; prefer it in C++20 codebases.
→ Deep dive: std::thread & jthread and std::thread Internals
How do you debug a deadlock?¶
Deadlocks come from inconsistent lock ordering. Debug with GDB all-stop mode (see all threads' backtraces at the hang), TSan (-fsanitize=thread) or Helgrind for happens-before violations; fix with std::scoped_lock multi-lock acquisition, lock hierarchies, and timeout-based retry design.
→ Deep dive: Debugging Deadlocks · GDB Multi-Thread All-Stop · Helgrind Concurrency Checks
What is false sharing and how do you fix it?¶
When two threads write different variables that share one 64-byte cache line, coherence traffic serializes them. Fix with padding/alignas(64) (or std::hardware_destructive_interference_size). Symptom: parallel code that scales worse than serial — this is a favorite senior-level question.
→ Deep dive: False Sharing & Cache Lines
When does the C++17 parallel STL help — and when not?¶
std::execution::par parallelizes the 69 algorithms; wins when per-element work dominates scheduling overhead; beware iterator validity across threads and that par without unseq doesn't vectorize. Combine with SIMD for memory-bound loops.
→ Deep dive: C++17 Parallel STL and C++ SIMD Vectorization
8. C Interview Questions Every C++ Candidate Should Know¶
These C-language fundamentals still appear in C++ interviews (especially systems/embedded roles):
malloc/freemechanics and alignment — covered in Hunting Memory Leaks in Practice- Pointer arithmetic and
sizeofon arrays vs pointers — The C++ sizeof Operator structlayout, padding, and bit fields — C++ struct · C++ Bit Fieldsuniontype safety — C++ union- Preprocessor: macros, conditional compilation, include guards — C++ Macros & Conditional Compilation
- Storage duration and linkage (
static,extern) — C++ static Members & Lifetime · C++ extern & Linkage - Implementing polymorphism by hand — C-Style Polymorphism in C++
- String/number conversions (
atoi,strtol) — Converting string to int
Also see the companion page std::string Interview Questions for string-specific deep dives (SSO, ABI compatibility, conversions).
How to Study From This List¶
- Answer out loud first, then read the deep dive — interviews grade explanation quality, not memorization.
- Follow the sections in order for systematic prep, or jump to your weakest area.
- Every deep dive compiles its examples against real STL/libstdc++ sources, so you can answer the "but how is it actually implemented?" follow-up.
Questions or want to discuss an answer? Open an issue on CPlusPlusThings or contact the author.