面试题答案
一键面试实现思路
- 自定义内存分配器:继承自
std::allocator
,重写allocate
和deallocate
方法,实现自定义的内存分配和释放逻辑。 - 智能指针封装:使用
std::unique_ptr
或std::shared_ptr
,结合自定义的删除器,确保对象在异常情况下也能正确释放内存。 - 异常安全设计:在构造函数和析构函数中使用异常安全的代码结构,如RAII(Resource Acquisition Is Initialization)机制,确保对象在创建和销毁过程中遇到异常时资源能正确管理。
关键代码示例
#include <iostream>
#include <memory>
// 自定义内存分配器
template <typename T>
class MyAllocator : public std::allocator<T> {
public:
using std::allocator<T>::allocator;
T* allocate(std::size_t n) {
// 自定义内存分配逻辑
void* p = std::malloc(n * sizeof(T));
if (!p) {
throw std::bad_alloc();
}
return static_cast<T*>(p);
}
void deallocate(T* p, std::size_t n) {
// 自定义内存释放逻辑
std::free(p);
}
};
// 自定义删除器
template <typename T>
struct MyDeleter {
void operator()(T* p) const {
// 自定义对象销毁逻辑
delete p;
}
};
class MyClass {
public:
MyClass() {
std::cout << "MyClass constructed" << std::endl;
}
~MyClass() {
std::cout << "MyClass destructed" << std::endl;
}
};
int main() {
// 使用自定义内存分配器和智能指针
std::unique_ptr<MyClass, MyDeleter<MyClass>> ptr(
new (MyAllocator<MyClass>().allocate(1)) MyClass(),
MyDeleter<MyClass>()
);
try {
// 可能抛出异常的代码块
throw std::runtime_error("Exception occurred");
} catch (const std::exception& e) {
std::cerr << "Caught exception: " << e.what() << std::endl;
}
// 智能指针会在作用域结束时调用自定义删除器,确保对象正确销毁
return 0;
}
在上述代码中:
MyAllocator
类自定义了内存分配和释放逻辑。MyDeleter
类定义了对象的销毁逻辑。std::unique_ptr
结合自定义删除器MyDeleter
,在异常情况下也能保证对象的正确销毁。