在 C++11 引入了智能指针其主要目的是简化内存管理,避免手动管理内存时可能导致的内存泄漏和悬空指针问题。
本文将详细介绍 std::unique_ptr
的基本使用方法。
1. 什么是
std::unique_ptr
?
std::unique_ptr
是 C++ 标准库中的一种智能指针类型,它独占所管理的动态内存对象。即同一时间只能有一个
unique_ptr
对象指向某个内存区域。当
unique_ptr
被销毁或超出作用域时,它自动释放所管理的内存,从而避免内存泄漏。
2. 如何创建和初始化
std::unique_ptr
?创建
unique_ptr
最常见的方式是使用std::make_unique
函数。该函数不仅可以创建一个智能指针,还会在堆上分配内存并初始化它。
示例代码:
#include<iostream> #include<memory> // 引入智能指针功能 int main() { std::unique_ptr<int> t1 = std::make_unique<int>(10); // 创建并初始化 std::cout << *t1 << std::endl; // 访问智能指针指向的值 return 0; }
std::make_unique<int>(10)
创建了一个unique_ptr<int>
,并将整数 10 存储在堆内存中。- 通过解引用操作符
*
可以访问指向的值。
3. std::unique_ptr
的常用操作
3.1 转移所有权
unique_ptr
不允许复制,只能转移所有权。可以使用
std::move
来将unique_ptr
的所有权从一个指针转移到另一个指针。
示例代码:
#include<iostream> #include<memory> int main() { std::unique_ptr<int> t1 = std::make_unique<int>(10); // 创建并初始化 std::cout << *t1 << std::endl; // 访问值 std::unique_ptr<int> t2 = std::move(t1); // 转移所有权 t2.reset(new int(20)); // 重置为一个新的对象 if (t1) { std::cout << "t1 is not null" << std::endl; } else { std::cout << "t1 is now null" << std::endl; // t1 被移动后不再指向任何内存 } std::cout << *t2 << std::endl; // 输出新的值 20 return 0; }
std::move(t1)
将t1
的所有权转移给t2
,之后t1
不再管理内存。reset()
可以重置t2
指向新的对象,并释放原先的内存。
3.2 判断是否为空
unique_ptr
可以直接与nullptr
进行比较,来检查是否为空。
示例代码:
if (t1) { // t1 不为空 } else { // t1 为空 }
3.3 获取裸指针
虽然
unique_ptr
是为了避免裸指针带来的内存问题,但有时我们仍然需要获取它所管理的裸指针,可以通过get()
方法。
示例代码:
int* rawPtr = t2.get(); // 获取裸指针
4. 在类中使用
std::unique_ptr
std::unique_ptr
也可以用于类成员,自动管理类的动态内存。
示例代码:
#include<iostream> #include<memory> class Person { public: void show() { std::cout << "Person class" << std::endl; } }; int main() { std::unique_ptr<Person> t1 = std::make_unique<Person>(); t1->show(); // 调用成员函数 return 0; }
在这个示例中,
t1
是一个unique_ptr
,它管理一个Person
对象。当t1
超出作用域时,Person
对象会被自动销毁。
5. 自定义删除器
std::unique_ptr
允许用户自定义删除器,以便在销毁对象时执行额外的操作,比如释放其他资源。
示例代码:
#include<iostream> #include<memory> class Person { public: ~Person() { std::cout << "Person is destroyed" << std::endl; } }; struct CustomDeleter { void operator()(Person* p) const { std::cout << "Custom delete called" << std::endl; delete p; // 自定义删除操作 } }; int main() { std::unique_ptr<Person, CustomDeleter> t1(new Person()); // 自定义删除器将在 t1 超出作用域时被调用 return 0; }
总结
std::unique_ptr
是 C++ 中管理动态内存的强大工具,能够有效避免内存泄漏和悬空指针等问题。通过 std::make_unique
创建、使用 std::move
转移所有权、以及自定义删除器来处理内存清理,unique_ptr
提供了简洁且安全的内存管理方式。