C++ · 2 · Classes & RAII8 / 36 · 22%
RAII — Resource Acquisition Is Initialization
The single most important idiom in C++: lifetime owns the resource.
Examples: destructor, scope guard, lock_guard
shortcuts: ← prev · → next · M mark
1
The Idea
Acquire in the constructor, release in the destructor. The compiler runs cleanup for you.
Example
example
class File {
std::FILE* f_;
public:
explicit File(const char* path) : f_(std::fopen(path, "r")) {
if (!f_) throw std::runtime_error("open failed");
}
~File() { if (f_) std::fclose(f_); }
File(const File&) = delete; // non-copyable
File& operator=(const File&) = delete;
};2
Exception Safety for Free
Stack unwinding runs every destructor on the way out.
Manual cleanup
| step | risk |
|---|---|
| fopen | — |
| throw | fclose skipped |
| fclose | never runs |
RAII
| step | risk |
|---|---|
| File f{...} | — |
| throw | unwinding |
| ~File() | always runs |
No goto cleanup, no forgotten branch.
3
Standard RAII Types
The library already wraps most resources.
Example
example
std::lock_guard<std::mutex> lk(m); // unlocks on scope exit
std::unique_ptr<Widget> w = std::make_unique<Widget>();
std::fstream file{"data.txt"}; // closes itself
std::vector<int> v(1000); // frees itself4
Destructor Rules
One rule you must never break.
WATCH OUT
Never let an exception escape a destructor — during unwinding that calls std::terminate. Catch and log inside.
Interview question
Why does a base class with virtual functions need a virtual destructor?