C++ CPE study materials
C++ CPE study resources

C++ CPE flashcards

C++ CPE · Build recall with a focused review session.

32 cards. Read the term and the definition here. The deck at the top of this page is optional.

Preprocessor vs compiler vs linker
The preprocessor performs textual substitution such as #include and #define. The compiler translates each source file into an object file. The linker merges object files and libraries, resolving external symbols into an executable.
main function return value
int main() is the program entry point. Returning 0 or reaching the closing brace without a return statement signals successful termination; any nonzero value signals failure to the calling environment.
std::endl versus newline
std::endl inserts a newline character and then flushes the output stream, which can be slower in loops. The plain character '\n' inserts only a newline and leaves flushing to the stream's normal buffering.
Integer division truncation
When both operands are integers, division truncates toward zero, so 7/2 yields 3 and -7/2 yields -3. The remainder operator takes the sign of the left operand, so -7 % 2 yields -1.
const versus constexpr
A const object is read-only after initialization and may be initialized at run time. A constexpr object must be initialized with a compile-time constant expression, so it can be used where a constant is required.
Uninitialized local variable hazard
A local variable of built-in type declared without an initializer holds an indeterminate value. Reading that value is undefined behavior, so such variables must always be initialized before use.
Reference binding rules
A reference is an alias that must be bound at initialization and cannot later be reseated to another object. It has no null state, unlike a pointer, which can be reassigned or set to nullptr.
Pass by const reference
Passing a parameter as const reference lets a function read a large object without copying it while preventing modification. Use plain value for small types and non-const reference only when the caller's object must change.
switch fall-through
In a switch statement, execution continues into the next case label unless a break or return exits. Grouping case labels without statements between them is the standard way to share one handler.
do-while loop guarantee
A do-while loop evaluates its condition after executing the body, so the body always runs at least once. A plain while loop checks first and may execute the body zero times.
Default arguments rule
Default argument values may be specified only once for a function, normally in its declaration in a header. A call omitting an argument uses the default; arguments are matched left to right.
Function overloading resolution
Overloads are distinguished by their parameter lists, including number and types. The return type alone cannot distinguish overloads, and the compiler selects the best match by conversion ranking.
Scope resolution operator
The :: operator accesses a name in a namespace or the global scope. It resolves a global variable shadowed by a local of the same name and qualifies standard library names such as std::cout.
sizeof and size_t
sizeof is a compile-time operator returning the size in bytes of a type or object as std::size_t, an unsigned integer type. Signed and unsigned mixing in comparisons can cause surprising conversions.
Signed integer overflow
Arithmetic that exceeds the range of a signed integer type is undefined behavior, so compilers may assume it never happens. Unsigned arithmetic wraps modulo two to the power of the type's bit width.
Range-based for loop
A range-based for loop iterates over a sequence, binding each element in turn. Use const auto& to avoid copies and modifications; use auto& to modify elements in place during iteration.
Member initialization order
Class members are initialized in the order they are declared in the class, not the order written in the constructor's initializer list. Const members and references must be initialized in that list.
Default class access
Members of a class declared with the class keyword are private by default. Members of a struct are public by default; the two keywords otherwise define identical types.
Rule of three and five
If a class defines a destructor, copy constructor, or copy assignment operator, it usually needs all three, plus the move constructor and move assignment operator for efficient resource transfer.
Virtual destructor requirement
Deleting a derived object through a base class pointer requires the base destructor to be virtual. Otherwise the derived destructor is not called, causing undefined behavior and leaked resources.
Pure virtual function
A virtual member declared with = 0 is pure and makes its class abstract. Abstract classes cannot be instantiated directly but can serve as interfaces implemented by derived classes.
override specifier
The override keyword after a member function declaration tells the compiler the function must override a base virtual function. A mismatched signature then becomes a compile error instead of silent hiding.
new and delete pairing
Memory from new must be released with delete, and memory from new[] with delete[]. Mixing the forms, or deleting the same pointer twice, is undefined behavior.
unique_ptr ownership
std::unique_ptr owns its object exclusively, cannot be copied, and can be moved to transfer ownership. It frees the object automatically, and std::make_unique constructs it safely without raw new.
shared_ptr reference counting
std::shared_ptr shares ownership through a reference count; the object is destroyed when the last owner is released. Cyclic references keep the count above zero, so std::weak_ptr breaks cycles.
Vector iterator invalidation
Inserting into a std::vector may reallocate its buffer, invalidating all iterators, pointers, and references to elements. Erasing invalidates iterators at and after the erased position.
Half-open iterator range
Standard algorithms take a range defined by begin and end iterators, where end points one past the last element. The range is empty when begin equals end, and loops compare with !=.
Erase-remove idiom
To remove elements matching a value from a sequence container, call std::remove or std::remove_if, then container erase from the returned iterator to end. This avoids invalidating iterators mid-loop.
Exception safety and unwinding
When an exception propagates, destructors of fully constructed local objects run during stack unwinding. Throwing from a destructor during unwinding calls std::terminate, so destructors should not throw.
Catch by const reference
Catching exceptions by const reference avoids slicing derived exception types and avoids unnecessary copies. Throwing by value creates the exception object, which the runtime manages until the handler finishes.
noexcept and terminate
A function marked noexcept promises not to let exceptions escape. If an exception does propagate out of it, the standard calls std::terminate, so mark only functions that truly cannot throw.
Operator overloading as free function
A free operator function takes both operands explicitly, allowing conversions on the left operand. A member operator receives the left operand as the implicit this pointer instead.