Modern C++ Programming
Learn the fundamentals and advanced features of Modern C++ to build efficient, maintainable, and high-performance applications.
Illustration of a simple physics simulation
Chapter 3. Functions, Interfaces, and Modular Design

Functions are the smallest unit of behavior in C++. Interfaces are the contracts that define how parts of a system communicate. Modular design is the discipline that keeps your codebase clean, scalable, and understandable.

This chapter teaches you how modern C++ uses functions and interfaces to build modular systems — the foundation for everything from small libraries to full engines.

Functions Express Intent

A good function answers three questions:

  1. What does it do?
  2. What does it need?
  3. What does it return?

Modern C++ encourages functions that are:

Example of clear intent:

float Length(const Vec3& v);

Example of unclear intent:

float doStuff(Vec3* a, Vec3* b);

The second version hides ownership, purpose, and behavior.

Function Signatures Communicate Ownership

Modern C++ uses function signatures to express ownership:

Pass by value
The function receives its own copy.
void Translate(Vec3 delta);
Pass by const reference
The function reads the value but does not modify it.
void SetColor(const Color& c);
Pass by non const reference
The function modifies the caller’s value.
void Normalize(Vec3& v);
Pass by pointer
The function may receive nullptr.
void AttachChild(Node* child);
Return by value
Modern C++ makes this cheap due to NRVO and move semantics.
Vec3 Add(const Vec3& a, const Vec3& b);

Clear ownership leads to clear architecture.

Pure Functions vs Mutating Functions

A pure function has no side effects:

float Dot(const Vec3& a, const Vec3& b);

A mutating function changes state:

void Rotate(Transform& t, float angle);

Modern C++ encourages pure functions whenever possible because they:

Mutating functions are used when behavior is intentional and meaningful.

Interfaces Define Contracts

An interface is a promise:

In C++, interfaces are expressed through:

Example of a simple interface:

class Drawable {
public:
    virtual void Draw() const = 0;
    virtual ~Drawable() = default;
};

This defines a contract without specifying implementation.

Abstract Classes and Polymorphism

Abstract classes define behavior without data.

class InputDevice
{
public:
    virtual bool IsPressed(int key) const = 0;
    virtual ~InputDevice() = default;
};

Derived classes implement the behavior:

class Keyboard : public InputDevice
{
public:
    bool IsPressed(int key) const override;
};

Modern C++ uses polymorphism sparingly — only when dynamic behavior is required.

Static Polymorphism (Templates and Concepts)

Static polymorphism avoids virtual calls:

template<typename T>
void Draw(const T& drawable)
{
    drawable.Draw();
}

This is resolved at compile time and is often faster.

C++20 concepts make constraints explicit:

template<typename T>
concept DrawableConcept = requires(T t)
{
    { t.Draw() } -> std::same_as<void>;
};

Use static polymorphism when:

Designing Clean Interfaces

A good interface:

Example of a clean interface:

class Timer
{
public:
    float DeltaTime() const;
    void Update();
};

Example of a poor interface:

class Timer
{
public:
    float* GetInternalPointer();
};

The second version leaks internal representation.

Modular Design Through Header Boundaries

Headers define module boundaries.

A good header:

Example:

// Transform.h
#pragma once
#include "Vec3.h"

struct Transform
{
    Vec3 position;
    Vec3 rotation;
    Vec3 scale;
};

This header is clean, minimal, and modular.

Separation of Interface and Implementation

Modern C++ encourages:

This separation:

Example:

// Math.h
float Dot(const Vec3& a, const Vec3& b);

// Math.cpp
float Dot(const Vec3& a, const Vec3& b)
{
    return a.x*b.x + a.y*b.y + a.z*b.z;
}
Designing Modules That Scale

A module should:

Examples of good modules:

Each module has a clear purpose and clean boundaries.

Conclusion

In this chapter, you learned:

These principles prepare you for the architectural chapters that follow.