Post

RAII & SOLID — Core Design Principles in C++

RAII & SOLID — Core Design Principles in C++

RAII & SOLID — Core Design Principles


Prerequisites

1
- C++

1. RAII (Resource Acquisition Is Initialization)

RAII is a C++ design principle where resource allocation and deallocation are tied to object lifetime.

  • Resource is acquired in constructor
  • Resource is released in destructor

Main Key Concept

  • resource tied to object lifetime
  • constructor → acquire
  • destructor → release
  • core idiom in C++

Why It Matters

In C++, you manage resources manually:

  • memory
  • file handles
  • mutex locks
❌ Without RAII
1
2
3
4
5
6
7
8
9
10
void process()
{
    FILE* f = fopen("file.txt", "r");

    if (!f) return;

    // ... do work

    fclose(f); // might be skipped if error occurs
}
  • early return
  • exception
  • missing cleanup

→ resource leak

✔ With RAII
1
2
3
4
5
6
7
8
#include <fstream>

void process()
{
    std::ifstream f("file.txt");

    // automatically closed when f goes out of scope
}

Destructor guarantees cleanup ✔

RAII with Mutex

1
2
3
4
5
6
7
8
std::mutex m;

void work()
{
    std::lock_guard<std::mutex> lock(m);

    // critical section
}
  • lock acquired
  • automatically released at scope end

Key Benefits

  • exception safety
  • no resource leaks
  • cleaner code
  • deterministic destruction

2. SOLID Principles

SOLID is a set of design principles that make software more maintainable, flexible, and scalable.

2-1. S — Single Responsibility Principle (SRP)

A class should have only one reason to change.

❌ Bad

1
2
3
4
5
6
class Report
{
public:
    void generate();
    void saveToFile();
};
  • generation + file I/O mixed

✔ Good

1
2
3
4
5
6
7
8
9
10
11
class ReportGenerator
{
public:
    void generate();
};

class ReportSaver
{
public:
    void save();
};

2-2. O — Open/Closed Principle (OCP)

Open for extension, closed for modification.

❌ Bad
1
2
if (type == "A") ...
else if (type == "B") ...
✔ Good
1
2
3
4
5
6
7
8
9
10
11
class Shape
{
public:
    virtual double area() = 0;
};

class Circle : public Shape
{
public:
    double area() override { ... }
};
  • add new types without modifying existing code

2-3. L — Liskov Substitution Principle (LSP)

Derived classes must be replaceable for their base class.

❌ Bad

1
2
3
4
5
6
7
8
9
10
11
class Bird
{
public:
    virtual void fly();
};

class Penguin : public Bird
{
public:
    void fly() override { throw; }
};
  • violates expectation
✔ Good
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Bird
{
};

class FlyingBird : public Bird
{
public:
    virtual void fly() = 0;
};

class Sparrow : public FlyingBird
{
public:
    void fly() override { /* OK */ }
};

class Penguin : public Bird
{
};

2-4. I — Interface Segregation Principle (ISP)

Do not force clients to depend on unused interfaces.

❌ Bad
1
2
3
4
5
6
class Machine
{
public:
    virtual void print();
    virtual void scan();
};
✔ Good
1
2
3
4
5
6
7
8
9
10
11
class Printer
{
public:
    virtual void print();
};

class Scanner
{
public:
    virtual void scan();
};

2-5. D — Dependency Inversion Principle (DIP)

Depend on abstractions, not concrete implementations.

❌ Bad
1
2
3
4
5
6
class Engine {};

class Car
{
    Engine engine;
};
✔ Good
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class IEngine
{
public:
    virtual void start() = 0;
};

class GasEngine : public IEngine
{
public:
    void start() override
    {
        std::cout << "Gas engine start\n";
    }
};

class ElectricEngine : public IEngine
{
public:
    void start() override
    {
        std::cout << "Electric engine start\n";
    }
};

class Car
{
    IEngine* engine;

public:
    Car(IEngine* e) : engine(e) {}

    void start()
    {
        engine->start(); // virtual dispatch
    }
};
1
2
3
4
5
6
7
8
9
10
11
int main()
{
    GasEngine gas;
    ElectricEngine electric;

    Car car1(&gas);
    Car car2(&electric);

    car1.start(); // Gas engine start
    car2.start(); // Electric engine start
}

RAII & SOLID together in Practice

In real systems:

  • RAII → safe resource handling
  • SOLID → clean architecture

Example

1
2
3
4
5
6
7
class FileProcessor
{
    std::ifstream file; // RAII

public:
    void process();     // SRP
};
This post is licensed under CC BY 4.0 by the author.