面试题答案
一键面试RAII原理
RAII(Resource Acquisition Is Initialization)机制核心在于将资源获取和对象生命周期绑定。当对象被创建(初始化)时,获取所需资源;当对象被销毁(析构)时,释放所获取的资源。这利用了C++中栈对象自动管理生命周期的特性,避免了手动管理资源时容易出现的资源泄漏等问题。
利用RAII确保线程崩溃不导致进程退出
1. 管理动态分配内存
#include <iostream>
#include <thread>
#include <memory>
class MemoryRAII {
public:
MemoryRAII(size_t size) : data(new int[size]) {
std::cout << "Memory allocated" << std::endl;
}
~MemoryRAII() {
delete[] data;
std::cout << "Memory deallocated" << std::endl;
}
private:
int* data;
};
void threadFunction() {
MemoryRAII mem(10);
// 模拟线程崩溃
throw std::runtime_error("Thread crashed");
}
int main() {
try {
std::thread t(threadFunction);
t.join();
} catch (const std::exception& e) {
std::cerr << "Caught exception: " << e.what() << std::endl;
// 进程不会退出,因为MemoryRAII对象在栈上,异常抛出时会自动析构释放内存
}
return 0;
}
2. 管理文件句柄
#include <iostream>
#include <thread>
#include <fstream>
class FileRAII {
public:
FileRAII(const std::string& filename) : file(filename) {
if (!file.is_open()) {
throw std::runtime_error("Failed to open file");
}
std::cout << "File opened" << std::endl;
}
~FileRAII() {
if (file.is_open()) {
file.close();
std::cout << "File closed" << std::endl;
}
}
private:
std::ofstream file;
};
void threadFunction2() {
FileRAII file("test.txt");
// 模拟线程崩溃
throw std::runtime_error("Thread crashed");
}
int main2() {
try {
std::thread t(threadFunction2);
t.join();
} catch (const std::exception& e) {
std::cerr << "Caught exception: " << e.what() << std::endl;
// 进程不会退出,因为FileRAII对象在栈上,异常抛出时会自动析构关闭文件
}
return 0;
}
在上述代码中,无论是动态分配内存还是文件句柄,都通过RAII机制在对象生命周期结束时自动释放资源。即使线程发生崩溃,由于栈上对象的自动析构,资源能够得到正确释放,从而避免因资源泄漏等问题导致进程退出。