题目
智能指针的基本使用与所有权
信息
- 类型:问答
- 难度:⭐
考点
智能指针基本概念,std::unique_ptr使用,内存管理
快速回答
std::unique_ptr 是C++11引入的智能指针,用于管理动态分配内存的独占所有权。主要特点:
- 独占所有权:同一时间只能有一个unique_ptr指向对象
- 自动释放:离开作用域时自动删除托管对象
- 轻量高效:几乎无额外开销
基本用法示例:
#include <memory>
void demo() {
// 创建unique_ptr管理int内存
std::unique_ptr<int> ptr(new int(10));
// 使用指针操作
*ptr = 20;
// 自动释放内存(无需delete)
}
## 解析
1. 核心原理
std::unique_ptr 通过RAII(资源获取即初始化)机制管理动态内存:
- 独占所有权:通过禁用拷贝构造函数/赋值运算符实现(允许移动语义)
- 自动释放:析构函数自动调用delete(或自定义删除器)
- 零开销抽象:编译期优化,运行时无额外开销
2. 代码示例详解
#include <iostream>
#include <memory>
class Resource {
public:
Resource() { std::cout << "Resource created\n"; }
~Resource() { std::cout << "Resource destroyed\n"; }
void use() { std::cout << "Using resource\n"; }
};
int main() {
// 创建unique_ptr(C++14推荐make_unique)
std::unique_ptr<Resource> res = std::make_unique<Resource>();
// 访问对象成员
res->use();
// 转移所有权(移动语义)
std::unique_ptr<Resource> res2 = std::move(res);
if(!res) {
std::cout << "res is now empty\n";
}
// res2离开作用域自动释放Resource
return 0;
}
输出结果:
Resource created
Using resource
res is now empty
Resource destroyed
3. 最佳实践
- 优先使用make_unique(C++14+):避免显式new,更安全高效
- 禁止拷贝操作:所有权转移必须使用std::move
- 管理数组:
std::unique_ptr<int[]> arr(new int[5]) - 自定义删除器:支持特殊资源清理(如文件句柄)
4. 常见错误
- 错误1:尝试拷贝unique_ptr
std::unique_ptr<int> p1(new int(5)); std::unique_ptr<int> p2 = p1; // 编译错误! - 错误2:与裸指针混用导致重复释放
int* raw = new int(10); std::unique_ptr<int> up(raw); // ... delete raw; // 运行时错误!双重释放 - 错误3:返回局部unique_ptr的引用(应直接返回值)
5. 扩展知识
- 与shared_ptr对比:unique_ptr无引用计数开销,性能更优
- 自定义删除器示例:
auto file_deleter = [](FILE* f) { fclose(f); }; std::unique_ptr<FILE, decltype(file_deleter)> file(fopen("test.txt", "r"), file_deleter); - C++17改进:支持数组的operator[]访问