unique_ptr
std::unique_ptr
是 C++ 中的一种智能指针,它表示对其所指向对象的独占所有权。,它表示对象的唯一所有权。std::unique_ptr 实例在离开作用域时会自动删除其所指向的对象,以下是 std::unique_ptr
的一些常见用法:
- 创建
std::unique_ptr
:你可以使用new
关键字创建一个std::unique_ptr
:
std::unique_ptr<int> p1(new int(5));
但是,更推荐的方式是使用 std::make_unique
函数,这样可以避免原始指针暴露,并提供更好的异常安全性:
std::unique_ptr<int> p1 = std::make_unique<int>(5);
- 访问
std::unique_ptr
所指向的对象:你可以使用*
和->
运算符来访问std::unique_ptr
所指向的对象:
*p1 = 10; // 使用 * 运算符
p1->method(); // 使用 -> 运算符,假设 p1 指向的对象有一个名为 method 的成员函数
- 移动
std::unique_ptr
:由于std::unique_ptr
表示独占所有权,所以你不能复制std::unique_ptr
,但你可以移动它:
std::unique_ptr<int> p2 = std::move(p1); // 现在 p2 拥有对象,p1 不再拥有对象
- 删除
std::unique_ptr
所指向的对象:当std::unique_ptr
被销毁(例如,当它离开其作用域)时,它会自动删除其所指向的对象。你也可以手动删除对象,方法是调用std::unique_ptr::reset
方法:
p2.reset(); // 删除 p2 所指向的对象,现在 p2 不再指向任何对象
- 检查
std::unique_ptr
是否为空:你可以像检查原始指针一样检查std::unique_ptr
是否为空:
if (p2) { // 如果 p2 不为空
// ...
}
传递给函数
std::unique_ptr
的设计目标是拥有其所指向的对象的独占所有权,因此你不能通过复制将 std::unique_ptr
传递给函数。但是,你可以通过引用或移动语义将 std::unique_ptr
传递给函数。
- 通过引用传递:如果你的函数只需要访问
std::unique_ptr
所指向的对象,但不需要接管所有权,你可以将std::unique_ptr
作为常量引用传递:
void f(const std::unique_ptr<int>& p) {
// 访问 p 所指向的对象,但不接管所有权
std::cout << *p << std::endl;
}
- 通过移动语义传递:如果你的函数需要接管
std::unique_ptr
所指向的对象的所有权,你可以通过std::move
将std::unique_ptr
传递给函数:
void g(std::unique_ptr<int> p) {
// 接管 p 所指向的对象的所有权
*p = 10;
}
std::unique_ptr<int> p = std::make_unique<int>(5);
g(std::move(p)); // 将 p 的所有权移动到 g
在这个例子中,g(std::move(p))
将 p
的所有权移动到 g
。在这个调用之后,p
不再拥有其原来所指向的对象。
weak_ptr
std::weak_ptr
是 C++ 中的一种智能指针,它是 std::shared_ptr
的弱引用。std::weak_ptr
不会增加其所指向对象的引用计数,因此它不会阻止对象被删除。它通常用于解决 std::shared_ptr
的循环引用问题。
以下是 std::weak_ptr
的一些常见用法:
- 创建
std::weak_ptr
:你可以从std::shared_ptr
创建一个std::weak_ptr
:
std::shared_ptr<int> p1 = std::make_shared<int>(5);
std::weak_ptr<int> w1 = p1; // 创建一个弱引用
- 访问
std::weak_ptr
所指向的对象:由于std::weak_ptr
不拥有其所指向的对象,所以你不能直接通过std::weak_ptr
访问对象。你需要先将std::weak_ptr
提升为std::shared_ptr
:
if (std::shared_ptr<int> p2 = w1.lock()) { // 提升为 std::shared_ptr
std::cout << *p2 << std::endl; // 访问对象
} else {
std::cout << "Object has been deleted." << std::endl;
}
- 检查
std::weak_ptr
是否为空:你可以使用std::weak_ptr::expired
方法检查std::weak_ptr
是否为空:
if (w1.expired()) { // 如果 w1 为空
// ...
}
- 获取
std::weak_ptr
所指向的对象的引用计数:你可以使用std::weak_ptr::use_count
方法获取std::weak_ptr
所指向的对象的引用计数:
std::cout << w1.use_count() << std::endl; // 打印引用计数
请注意,std::weak_ptr
主要用于解决 std::shared_ptr
的循环引用问题。例如,如果你有两个类 A 和 B,它们互相持有对方的 std::shared_ptr
,那么这两个对象将永远不会被删除,因为它们的引用计数永远不会变为 0。在这种情况下,你可以使用 std::weak_ptr
来打破这个循环。
std::shared_ptr
,std::weak_ptr
和 std::unique_ptr
都是 C++ 中的智能指针,它们用于自动管理动态分配的内存,以防止内存泄漏。它们的主要区别在于所有权和生命周期管理:
-
std::unique_ptr
表示对其所指向对象的独占所有权。也就是说,同一时间只能有一个std::unique_ptr
指向一个给定的对象。当std::unique_ptr
被销毁时,它所指向的对象也会被删除。std::unique_ptr
不能被复制,但可以被移动,这意味着你可以将所有权从一个std::unique_ptr
转移到另一个std::unique_ptr
。 -
std::shared_ptr
允许多个std::shared_ptr
对象共享对同一个对象的所有权。std::shared_ptr
使用引用计数来跟踪有多少个std::shared_ptr
对象指向同一个对象。当最后一个std::shared_ptr
被销毁时,它所指向的对象也会被删除。 -
std::weak_ptr
是一种特殊的std::shared_ptr
,它不会增加其所指向对象的引用计数。这意味着std::weak_ptr
不会阻止其所指向的对象被删除。std::weak_ptr
主要用于解决std::shared_ptr
的循环引用问题。你可以通过std::weak_ptr::lock
方法将std::weak_ptr
提升为std::shared_ptr
,如果对象还存在,lock
方法会返回一个新的std::shared_ptr
,指向该对象,并增加其引用计数。如果对象已经被删除,lock
方法会返回一个空的std::shared_ptr
。
总的来说,std::unique_ptr
、std::shared_ptr
和 std::weak_ptr
提供了不同级别的所有权和生命周期管理,你可以根据你的具体需求选择使用哪一种。