491 字
2 分钟
11.RAII与构造析构
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;}