unique_ptr通过独占所有权和RAII机制自动管理内存,避免内存泄漏;它不可复制,只能通过std::move转移所有权,适用于单一所有者场景,性能优于shared_ptr,是现代C++资源管理的首选方案。

unique_ptr
unique_ptr
unique_ptr
unique_ptr
要使用
unique_ptr
std::make_unique
new
#include <iostream>
#include <memory> // 包含 unique_ptr 的头文件
#include <vector>
class MyObject {
public:
int id;
MyObject(int i) : id(i) {
std::cout << "MyObject " << id << " created." << std::endl;
}
~MyObject() {
std::cout << "MyObject " << id << " destroyed." << std::endl;
}
void doSomething() {
std::cout << "MyObject " << id << " is doing something." << std::endl;
}
};
// 函数返回 unique_ptr,所有权被转移
std::unique_ptr<MyObject> createObject(int id) {
std::cout << "Inside createObject." << std::endl;
return std::make_unique<MyObject>(id); // 返回时所有权会转移
}
void processObject(std::unique_ptr<MyObject> obj) { // 接收 unique_ptr,所有权转移到函数内部
std::cout << "Inside processObject." << std::endl;
if (obj) {
obj->doSomething();
}
// obj 在这里超出作用域,MyObject 会被销毁
std::cout << "Exiting processObject." << std::endl;
}
int main() {
// 1. 使用 std::make_unique 创建 unique_ptr
std::unique_ptr<MyObject> ptr1 = std::make_unique<MyObject>(1);
ptr1->doSomething(); // 访问对象成员
// 2. unique_ptr 不可复制,只能通过 std::move 转移所有权
// std::unique_ptr<MyObject> ptr2 = ptr1; // 编译错误!
std::unique_ptr<MyObject> ptr2 = std::move(ptr1); // 所有权从 ptr1 转移到 ptr2
if (ptr1) { // ptr1 现在是空的
std::cout << "ptr1 still holds an object." << std::endl;
} else {
std::cout << "ptr1 is now empty." << std::endl;
}
ptr2->doSomething(); // ptr2 现在拥有对象
// 3. 作为函数返回值
std::unique_ptr<MyObject> ptr3 = createObject(3);
ptr3->doSomething();
// 4. 作为函数参数(传递所有权)
processObject(std::move(ptr3)); // ptr3 的所有权转移到 processObject 内部
if (!ptr3) {
std::cout << "ptr3 is now empty after moving to processObject." << std::endl;
}
// 5. unique_ptr 管理数组
std::unique_ptr<MyObject[]> objArray = std::make_unique<MyObject[]>(2);
objArray[0].id = 4;
objArray[1].id = 5;
objArray[0].doSomething();
objArray[1].doSomething();
// 当 objArray 超出作用域时,MyObject[4] 和 MyObject[5] 都会被销毁
// 6. 自定义删除器:当需要用非 delete 方式释放资源时
// 比如文件句柄,需要 fclose
auto file_closer = [](FILE* f) {
if (f) {
std::cout << "Closing file..." << std::endl;
fclose(f);
}
};
std::unique_ptr<FILE, decltype(file_closer)> file_ptr(fopen("test.txt", "w"), file_closer);
if (file_ptr) {
fputs("Hello unique_ptr!\n", file_ptr.get());
std::cout << "File opened and written to." << std::endl;
} else {
std::cerr << "Failed to open file!" << std::endl;
}
// file_ptr 超出作用域时,file_closer 会被调用来关闭文件
std::cout << "End of main function." << std::endl;
return 0;
}通过上面的例子,我们可以看到
unique_ptr
delete
立即学习“C++免费学习笔记(深入)”;
回想一下 C++ 早期,我们处理动态内存主要靠
new
delete
delete
delete
delete
if
delete
new
unique_ptr
unique_ptr
delete
delete
它还解决了异常安全问题。想象一下,如果在
new
delete
delete
unique_ptr
相比于 C++98/03 的
auto_ptr
unique_ptr
auto_ptr
unique_ptr
std::move
unique_ptr
当我们谈论 C++ 智能指针,除了
unique_ptr
shared_ptr
weak_ptr
最核心的区别在于它们对资源的所有权模型:
unique_ptr
unique_ptr
std::move
unique_ptr
shared_ptr
shared_ptr
shared_ptr
shared_ptr
weak_ptr
weak_ptr
shared_ptr
weak_ptr
shared_ptr
shared_ptr
lock()
lock()
shared_ptr
那么,何时选择
unique_ptr
unique_ptr
shared_ptr
unique_ptr
unique_ptr
shared_ptr
unique_ptr
unique_ptr
std::move
unique_ptr<T[]>
delete[]
简单来说,如果你不需要共享对象,也不需要处理复杂的生命周期依赖,
unique_ptr
尽管
unique_ptr
常见误区:
unique_ptr
unique_ptr
std::unique_ptr<MyObject> ptr1 = std::make_unique<MyObject>(1); // std::unique_ptr<MyObject> ptr2 = ptr1; // 编译错误!
如果你确实需要转移所有权,必须使用
std::move
unique_ptr<T>
new MyObject[10]
std::unique_ptr<MyObject[]>
std::unique_ptr<MyObject>
delete obj_ptr;
delete[] obj_ptr;
get()
get()
unique_ptr
unique_ptr
std::unique_ptr<MyObject> ptr = std::make_unique<MyObject>(1); MyObject* rawPtr = ptr.get(); // ptr 在这里被销毁了,rawPtr 变成悬空指针 // ... // rawPtr->doSomething(); // 危险!
new
std::make_unique
new
std::make_unique
std::make_unique
new
std::make_unique
最佳实践:
总是优先使用 std::make_unique
unique_ptr
利用 std::move
std::move
unique_ptr
std::move
避免 get()
get()
unique_ptr
MyObject&
善用自定义删除器处理特殊资源:
unique_ptr
new/delete
unique_ptr
// 示例见解决方案部分的文件关闭器
作为函数参数时,考虑传递引用或裸指针: 如果函数只是需要访问
unique_ptr
MyObject&
MyObject*
std::unique_ptr<MyObject>
void observeObject(const MyObject& obj) { /* ... */ }
void takeOwnership(std::unique_ptr<MyObject> obj) { /* ... */ }
// main
std::unique_ptr<MyObject> ptr = std::make_unique<MyObject>(1);
observeObject(*ptr); // 传递引用
takeOwnership(std::move(ptr)); // 转移所有权通过遵循这些实践,你可以充分发挥
unique_ptr
以上就是C++如何使用unique_ptr管理动态对象的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号