一篇搞懂C++ STL 智能指针std::unique_ptr
【摘要】 @TOC 前言在现代 C++ 编程中,内存管理是一个至关重要的方面。std::unique_ptr 是 C++11 引入的智能指针之一,它用于管理动态分配的对象,确保对象在适当的时候被销毁,防止内存泄漏。std::unique_ptr 是一种独占所有权的智能指针,这意味着同一时间只有一个 std::unique_ptr 实例可以拥有某个对象的所有权。 为什么使用 std::unique_pt...
@TOC
前言
在现代 C++ 编程中,内存管理是一个至关重要的方面。std::unique_ptr
是 C++11 引入的智能指针之一,它用于管理动态分配的对象,确保对象在适当的时候被销毁,防止内存泄漏。std::unique_ptr
是一种独占所有权的智能指针,这意味着同一时间只有一个 std::unique_ptr
实例可以拥有某个对象的所有权。
为什么使用 std::unique_ptr
- 自动内存管理:
std::unique_ptr
可以自动释放其管理的对象,避免了手动删除的麻烦。 - 独占所有权:
std::unique_ptr
确保在同一时间内只有一个指针拥有对象的所有权,从而防止了双重释放和悬空指针的问题。 - 性能优越:
std::unique_ptr
轻量且高效,适合用于需要动态分配内存的场景。
std::unique_ptr
的构造函数和操作函数
构造函数
-
默认构造函数
std::unique_ptr();
std::unique_ptr<int> p; // 创建一个空的 unique_ptr
-
构造函数(原始指针)
explicit std::unique_ptr(T* ptr);
std::unique_ptr<int> p(new int(10)); // 使用原始指针构造 unique_ptr
-
移动构造函数
std::unique_ptr(std::unique_ptr&& other) noexcept;
std::unique_ptr<int> p1(new int(20)); std::unique_ptr<int> p2(std::move(p1)); // 移动构造
成员函数
-
reset
void reset(T* ptr = nullptr);
std::unique_ptr<int> p(new int(30)); p.reset(new int(40)); // 释放旧对象并拥有新对象
-
release
T* release();
std::unique_ptr<int> p(new int(50)); int* rawPtr = p.release(); // 释放拥有权并返回原始指针 delete rawPtr; // 手动删除原始指针
-
get
T* get() const noexcept;
std::unique_ptr<int> p(new int(60)); int* rawPtr = p.get(); // 获取原始指针
-
operator*
T& operator*() const;
std::unique_ptr<int> p(new int(70)); std::cout << *p << std::endl; // 访问管理的对象
-
operator->
T* operator->() const;
struct MyClass { void display() const { std::cout << "Hello" << std::endl; } }; std::unique_ptr<MyClass> p(new MyClass()); p->display(); // 访问对象的成员函数
操作多个 std::unique_ptr
std::unique_ptr
不能直接共享所有权。如果需要多个智能指针管理同一个对象,必须使用 std::shared_ptr
。以下代码示例演示了如何操作和转移 std::unique_ptr
的所有权:
std::unique_ptr<int> p1(new int(80));
std::unique_ptr<int> p2 = std::move(p1); // p1 的所有权转移到 p2
if (!p1) {
std::cout << "p1 is empty" << std::endl;
}
if (p2) {
std::cout << "p2 owns the object with value: " << *p2 << std::endl;
}
示例代码
下面的示例展示了 std::unique_ptr
的各种构造函数和操作函数的用法:
#include <iostream>
#include <memory>
struct MyClass {
MyClass(int v) : value(v) {}
int value;
void display() const { std::cout << "Value: " << value << std::endl; }
};
int main() {
// 使用默认构造函数
std::unique_ptr<int> p1;
// 使用原始指针构造函数
std::unique_ptr<int> p2(new int(10));
std::cout << "p2: " << *p2 << std::endl;
// 使用移动构造函数
std::unique_ptr<int> p3(std::move(p2));
if (!p2) {
std::cout << "p2 is now empty" << std::endl;
}
// 使用 reset 函数
p3.reset(new int(20));
std::cout << "p3: " << *p3 << std::endl;
// 使用 release 函数
int* rawPtr = p3.release();
std::cout << "Released raw pointer value: " << *rawPtr << std::endl;
delete rawPtr; // 手动删除
// 使用 get 函数
std::unique_ptr<MyClass> p4(new MyClass(30));
MyClass* rawPtrClass = p4.get();
rawPtrClass->display();
// 使用 operator* 和 operator->
std::unique_ptr<MyClass> p5(new MyClass(40));
std::cout << "p5 value: " << p5->value << std::endl;
(*p5).display();
return 0;
}
总结
std::unique_ptr
是一个功能强大的智能指针,提供了对动态分配内存的独占所有权管理。它自动释放所管理的对象,避免了内存泄漏,并确保同一时间只有一个 std::unique_ptr
拥有对象的所有权。通过掌握 std::unique_ptr
的构造函数和操作函数,能够更安全和高效地管理动态内存。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)