491 字
2 分钟
11.RAII与构造析构
2025-02-15

RAII与构造析构#

  • RAII(Resource Acquisition Is Initialization):资源获取即初始化

当程序需要获取某个资源时(这个资源可以是文件、互斥量等),为了保证该资源能够被自动释放,使用一个Handler类封装资源。 即:

  • 在构造函数中,初始化操作资源。
  • 在析构函数中,释放资源。

示例:

  • 基于RAII实现的FileHandler
#include <iostream>
#include <fstream>
#include <string>
class FileHandler {
private:
std::fstream file;
std::string filename;
public:
// 构造函数:打开文件
explicit FileHandler(const std::string& filename, std::ios::openmode mode = std::ios::in | std::ios::out)
: filename(filename), file(filename, mode) {
if (!file.is_open()) {
throw std::runtime_error("Failed to open file: " + filename);
}
}
// 禁止拷贝构造和拷贝赋值,以避免资源重复管理
FileHandler(const FileHandler&) = delete;
FileHandler& operator=(const FileHandler&) = delete;
// 允许移动构造和移动赋值
FileHandler(FileHandler&& other) noexcept
: file(std::move(other.file)), filename(std::move(other.filename)) {}
FileHandler& operator=(FileHandler&& other) noexcept {
if (this != &other) {
file = std::move(other.file);
filename = std::move(other.filename);
}
return *this;
}
// 写入数据
void write(const std::string& data) {
if (file.is_open()) {
file << data;
}
}
// 读取数据
std::string read() {
if (!file.is_open()) {
throw std::runtime_error("File is not open.");
}
std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
return content;
}
// 关闭文件
void close() {
if (file.is_open()) {
file.close();
}
}
// 析构函数:自动关闭文件
~FileHandler() {
close();
}
};
int main() {
try {
FileHandler file("file.txt", std::ios::out | std::ios::trunc);
file.write("Hello, RAII FileHandler!\n");
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
  • 基于RAII实现的Lockguard
#include <iostream>
#include <mutex>
#include <stdexcept>
class LockGuard {
private:
std::mutex& mtx;
public:
// 构造函数,获取锁
explicit LockGuard(std::mutex& m) : mtx(m) {
mtx.lock();
std::cout << "build lockguard()" << std::endl;
}
// 禁止拷贝构造和拷贝赋值
LockGuard(const LockGuard&) = delete;
LockGuard& operator=(const LockGuard&) = delete;
// 允许移动构造和移动赋值
LockGuard(LockGuard&& other) noexcept : mtx(other.mtx) {
other.mtx.unlock(); // 确保旧对象不再持有锁
}
LockGuard& operator=(LockGuard&& other) noexcept = delete;
// 析构函数,释放锁
~LockGuard() {
mtx.unlock();
std::cout << "~lockguard()" << std::endl;
}
};
void safeFunction() {
static std::mutex mtx;
LockGuard lock(mtx);
// 受保护的临界区代码
std::cout << "Thread-safe operation\n";
throw std::runtime_error("Simulated error in safeFunction");
}
int main() {
try {
safeFunction();
} catch (const std::exception& e) {
std::cerr << "Caught exception: " << e.what() << std::endl;
}
return 0;
}
11.RAII与构造析构
https://chrisnake11.github.io/blog/posts/coding/c基础/11raii与构造析构/
作者
Zheyv
发布于
2025-02-15
许可协议
CC BY-NC-SA 4.0