C++

Lesson 01

RAII resource ownership

Use RAII objects so files, locks, and other resources release through scope instead of manual cleanup paths.

Good Code

src/review_file.cpp
#include <filesystem>
#include <fstream>
#include <stdexcept>
#include <string_view>

void save_review(const std::filesystem::path& path, std::string_view body)
{
    std::ofstream file(path);
    if (!file) {
        throw std::runtime_error("cannot open review file");
    }

    // RAII closes the file when the stream leaves scope.
    file << body;
    if (!file) {
        throw std::runtime_error("cannot write review file");
    }
}

Bad Code

review_file.cpp
#include <cstdio>

bool save_review(const char* path, const char* body)
{
    FILE* file = std::fopen(path, "w");
    if (file == nullptr) {
        return false;
    }

    if (std::fputs(body, file) == EOF) {
        // Early return skips the manual fclose call.
        return false;
    }

    std::fclose(file);
    return true;
}

Review Notes

What to review

Good Code

The good version uses an output stream whose destructor closes the file. Every exit path releases the resource, including exceptions raised after the write.

Bad Code

The bad version uses manual fclose and returns early on write failure. That path leaves the file open and hides any close-time error.

Takeaways

  • C++ resource code should tie acquisition to an object lifetime, so exits through return or exception still release the resource.