Skip to content
C++

OOP Quick Reference

C++ OOP cheatsheet — classes, access control, inheritance, virtual functions, abstract classes, and Rule of Five summary.

Class Anatomy

cpp
class Widget {
public:                          // public interface
    Widget(int id, std::string name);  // constructor
    ~Widget();                   // destructor
    Widget(const Widget&);       // copy constructor
    Widget& operator=(const Widget&);  // copy assignment
    Widget(Widget&&) noexcept;   // move constructor
    Widget& operator=(Widget&&) noexcept;  // move assignment

    int    id()          const;  // const getter
    void   set_name(std::string);// setter
    void   render()      const;  // behavior

protected:                       // accessible in subclasses
    void on_resize();

private:                         // implementation detail
    int         id_;
    std::string name_;
};

Access Control

cpp
class Foo {
public:    // anyone
    void use();

protected: // Foo + derived classes
    void helper();

private:   // Foo only
    int data_;

    friend class Bar;       // Bar can access private
    friend void baz(Foo&);  // baz can access private
};

Constructors

cpp
struct Point {
    int x, y;

    Point() : x{0}, y{0} {}                   // default
    Point(int x, int y) : x{x}, y{y} {}       // parameterized
    Point(const Point&) = default;             // copy — explicit default
    explicit Point(int v) : x{v}, y{v} {}     // prevent implicit conversion

    // Delegating (C++11)
    Point(int v) : Point{v, v} {}
};

// Aggregate initialization (no user-provided ctor needed)
struct Color { float r, g, b; };
Color red{1.0f, 0.0f, 0.0f};
Color blue{.b = 1.0f};  // C++20 designated init

Inheritance

cpp
struct Base {
    virtual void draw()    const = 0;  // pure virtual
    virtual void update()  {}          // virtual with default
    virtual ~Base() = default;         // always virtual dtor!
};

struct Derived : public Base {
    void draw()   const override final { }  // override + final
    // update() inherited from Base
};

struct Leaf final : Derived { };  // no further derivation

Rule of Five

cpp
class Resource {
public:
    ~Resource()                          // 1. destructor
    Resource(const Resource&)            // 2. copy ctor
    Resource& operator=(const Resource&) // 3. copy assign
    Resource(Resource&&) noexcept        // 4. move ctor
    Resource& operator=(Resource&&) noexcept  // 5. move assign
};

// Rule of Zero: if members handle themselves, declare none:
class Modern {
    std::unique_ptr<Foo> foo_;  // unique_ptr handles move+destroy
    std::string name_;          // string handles copy+move
    // No destructor/copy/move needed!
};

Virtual Dispatch

cpp
struct Animal {
    virtual void speak() const = 0;
    virtual ~Animal() = default;
};

struct Dog : Animal { void speak() const override { puts("Woof"); } };
struct Cat : Animal { void speak() const override { puts("Meow"); } };

std::vector<std::unique_ptr<Animal>> animals;
animals.push_back(std::make_unique<Dog>());
animals.push_back(std::make_unique<Cat>());

for (const auto& a : animals)
    a->speak();  // dynamic dispatch — Woof, Meow

Operator Overloading Summary

cpp
// Member: =, [], (), ->, (unary)
// Free:   +, -, *, /, ==, !=, <, >, <<, >>

struct Vec2 { float x, y; };

Vec2  operator+ (Vec2 a, Vec2 b)     { return {a.x+b.x, a.y+b.y}; }
Vec2& operator+=(Vec2& a, Vec2 b)    { a.x+=b.x; a.y+=b.y; return a; }
bool  operator==(const Vec2& a, const Vec2& b) = default;  // C++20
auto  operator<=>(const Vec2&, const Vec2&) = default;     // C++20

std::ostream& operator<<(std::ostream& os, const Vec2& v) {
    return os << '(' << v.x << ',' << v.y << ')';
}

Static Members

cpp
class Counter {
    static int count_;   // shared across all instances

public:
    Counter()  { ++count_; }
    ~Counter() { --count_; }

    static int count()  { return count_; }
    static void reset() { count_ = 0; }

    // C++17: inline static (define in header)
    inline static int instances = 0;
};

int Counter::count_ = 0;  // definition in .cpp

Counter::count();  // no object needed

Interfaces (Abstract Base Classes)

cpp
struct Drawable {
    virtual void draw(Canvas&)       const = 0;
    virtual BoundingBox bounds()     const = 0;
    virtual bool hit_test(Point pt)  const { return bounds().contains(pt); }
    virtual ~Drawable() = default;
};

struct Updateable {
    virtual void update(float dt)  = 0;
    virtual ~Updateable() = default;
};

// Multiple interface inheritance
struct Sprite : public Drawable, public Updateable {
    void draw(Canvas& c)   const override { /* ... */ }
    BoundingBox bounds()   const override { /* ... */ }
    void update(float dt)        override { /* ... */ }
};

Composition vs Inheritance

cpp
// Prefer composition ("has-a") over inheritance ("is-a")

// Inheritance: tight coupling, fragile base class
class LoggedVector : public std::vector<int> {
    // BAD: std::vector has no virtual dtor!
};

// Composition: wraps, controls interface
class LoggedVector {
    std::vector<int> data_;
public:
    void push_back(int x) {
        log("push_back");
        data_.push_back(x);
    }
    // delegate only the interface you need
};
Edit on GitHub