C++ OOP Track
Learning Objectives
Review every C++ OOP mechanism in one place and know which module covers it in depth.
Write idiomatic modern C++ classes (C++20/23).
Prerequisites: Stages 1–2.
Intuition and Definition
C++ gives you value semantics by default, deterministic destruction, zero-overhead abstractions and both run-time and compile-time polymorphism — and expects you to manage ownership explicitly.
Classes, access class/struct, public/protected/private, friend constructors, initializer lists, delegating, explicit, destructors
public/protected/private inheritance, virtual bases, final
virtual, override, pure virtual, vtables almost all overloadable, <=> templates, concepts, CRTP
RAII, unique_ptr/shared_ptr/weak_ptr, Rule of 0/3/5, move semantics exceptions, noexcept, std::expected RTTI: typeid, dynamic_cast sizeof, alignment, EBO, Pimpl
Why It Matters
C++ is the main OO language in embedded systems, automotive ECUs, games, finance and infrastructure software — exactly where object lifetime and performance matter most.
Syntax and Language Notes
Modern guidelines (C++ Core Guidelines): prefer values and unique_ptr, follow the Rule of Zero, mark single-argument constructors explicit, use override, make polymorphic bases' destructors virtual (or protected), avoid owning raw pointers, prefer std::expected/exceptions consistently, and constrain templates with concepts.
Complete Example
A compact tour: an abstract interface, RAII ownership, a value type with operators, a constrained template, move semantics, exceptions and RTTI.
#include <concepts>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <typeinfo>
#include <vector>
struct Celsius { // value type with operators
double v;
auto operator<=>(const Celsius&) const = default;
Celsius operator+(Celsius o) const { return {v + o.v}; }
};
std::ostream& operator<<(std::ostream& os, Celsius c) { return os << c.v << " C"; }
class Sensor { // interface
public:
virtual ~Sensor() = default;
virtual Celsius read() const = 0;
virtual std::string id() const = 0;
};
class Thermistor final : public Sensor {
std::string id_;
Celsius offset_;
public:
explicit Thermistor(std::string id, Celsius off = {0}) : id_(std::move(id)), offset_(off) {}
Celsius read() const override { return Celsius{88.5} + offset_; }
std::string id() const override { return id_; }
};
class Rack { // owns sensors: Rule of Zero, move-only
std::vector<std::unique_ptr<Sensor>> sensors_;
public:
void add(std::unique_ptr<Sensor> s) {
if (!s) throw std::invalid_argum
…coolant: 90 C
oil: 88.5 C
hot sensors: 1
dynamic type is Thermistor: 1
error: null sensorStep-by-Step Walkthrough
Celsius is a value type; defaulted <=> gives all comparisons.
Sensor is a pure interface with a virtual destructor; Thermistor is final.
Rack owns sensors through unique_ptr: it is automatically move-only and cleans up deterministically.
count accepts any callable satisfying std::predicate<const Sensor&>.
RTTI confirms the dynamic type; invalid input throws.
Common Mistakes
C++-specific pitfalls covered in this course: slicing (8), missing virtual destructor (4), owning raw pointers (13), shared_ptr cycles (13), dangling references/views (13), initializer order (5), name hiding (7), default arguments on virtuals (35), const members blocking assignment (59), side effects in assert (54).
Trade-offs and Alternatives
C++ gives control and performance at the price of complexity; much of modern C++ style is about *not* using features (raw new, manual memory management, deep inheritance).
Real-World Use
AUTOSAR Adaptive, game engines (Unreal), browsers (Chromium), databases, trading systems, robotics (ROS 2).
Practice
Q1. (Easy) Why is Rack move-only without any code?
Answer: Its std::vector<std::unique_ptr<Sensor>> member is move-only, so the implicitly generated copy operations are deleted.
Q2. (Medium) What does final on Thermistor enable besides preventing derivation?
Answer: Devirtualization: calls through a Thermistor reference can be resolved statically.
Q3. (Advanced) List three things you'd check in a C++ class review.
Answer: Ownership (Rule of Zero/Five, no owning raw pointers), polymorphic base correctness (virtual or protected destructor, override, no slicing), and exception safety/noexcept on moves and destructors (plus explicit constructors and const-correctness).
Interview Question
Q1. "What makes modern C++ OOP different from 'C with classes'?"
Answer: RAII and smart pointers instead of manual new/delete, value semantics with move semantics, the Rule of Zero, override/final, generic programming with templates and concepts (often replacing inheritance), std::variant/std::optional/std::expected for sum types and errors, ranges, and constexpr computation — with inheritance reserved for genuine run-time polymorphism.
Quick Quiz
Q1. Default copy semantics of C++ class objects?
Answer: Value (memberwise copy).
Q2. Which smart pointer by default?
Answer: std::unique_ptr.
Q3. What does override guarantee?
Answer: A compile error if the function doesn't override a base virtual.
Summary
C++ OOP = value semantics + RAII + explicit ownership + virtual and template polymorphism.
Related: Modules 2–17, 55–58.