面试题答案
一键面试RAII基本原理
RAII(Resource Acquisition Is Initialization),即资源获取即初始化。其核心思想是将资源(如内存、文件句柄、锁等)的获取绑定到对象的构造函数中,而资源的释放绑定到对象的析构函数中。当对象创建时,自动获取资源;当对象生命周期结束时(无论是正常结束还是因异常退出),自动释放资源。这样可以确保资源在其作用域结束时被正确释放,避免资源泄漏。
适用应用场景
- 内存管理
- 在C++中,使用
new
分配的内存需要使用delete
释放。如果在代码中有多个return
语句或者可能抛出异常的情况下,手动管理内存很容易遗漏释放操作,导致内存泄漏。使用RAII可以将内存管理交给对象。例如:
- 在C++中,使用
#include <iostream>
class MemoryResource {
public:
MemoryResource(size_t size) : data(new int[size]) {
std::cout << "Memory allocated" << std::endl;
}
~MemoryResource() {
delete[] data;
std::cout << "Memory deallocated" << std::endl;
}
private:
int* data;
};
int main() {
{
MemoryResource mr(10);
// 在mr的作用域内,内存已分配且在作用域结束时会自动释放
}
return 0;
}
- 文件操作
- 打开文件后需要在使用完毕后关闭文件。通过RAII,可以在构造函数中打开文件,在析构函数中关闭文件,确保文件始终能被正确关闭。示例如下:
#include <iostream>
#include <fstream>
class FileResource {
public:
FileResource(const char* filename) : file(filename) {
if (!file) {
throw std::runtime_error("Failed to open file");
}
std::cout << "File opened" << std::endl;
}
~FileResource() {
file.close();
std::cout << "File closed" << std::endl;
}
std::ofstream& getFile() {
return file;
}
private:
std::ofstream file;
};
int main() {
{
try {
FileResource fr("test.txt");
fr.getFile() << "Some data";
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
}
return 0;
}
- 互斥锁管理
- 在多线程编程中,为了保护共享资源,需要使用互斥锁。使用RAII可以简化锁的获取和释放流程,避免忘记释放锁导致死锁。例如:
#include <iostream>
#include <mutex>
class LockGuard {
public:
LockGuard(std::mutex& mtx) : mutex(mtx) {
mutex.lock();
std::cout << "Lock acquired" << std::endl;
}
~LockGuard() {
mutex.unlock();
std::cout << "Lock released" << std::endl;
}
private:
std::mutex& mutex;
};
std::mutex globalMutex;
void threadFunction() {
LockGuard lg(globalMutex);
// 在lg的作用域内,锁已获取且在作用域结束时会自动释放
std::cout << "Thread is accessing shared resource" << std::endl;
}