智能指针
智能指针
unique_ptr
脱离作用域,该指针就会被释放。不能复制这个指针。
weak_ptr
std::weak_ptr
是 C++11 标准库中的一个智能指针类型,用于解决 std::shared_ptr
循环引用的问题。std::weak_ptr
不控制所指向对象的生命周期,它只是观察一个由 std::shared_ptr
管理的对象。这意味着 std::weak_ptr
不会增加所指向对象的引用计数。
std::weak_ptr
的主要特点如下:
不控制对象的生命周期:与
std::shared_ptr
不同,std::weak_ptr
不拥有所指向对象的所有权。当最后一个std::shared_ptr
被销毁或重置时,无论是否有std::weak_ptr
指向该对象,对象都会被删除。避免循环引用:在复杂的对象结构中,两个或多个对象相互持有对方的
std::shared_ptr
可能导致循环引用,从而使这些对象无法被正确删除。通过使用std::weak_ptr
代替其中一个或多个std::shared_ptr
,可以打破循环引用,确保对象在不再需要时能够被正确删除。访问对象前需要锁定:由于
std::weak_ptr
不保证所指向的对象仍然存在(因为该对象可能已经被std::shared_ptr
删除),所以在访问对象之前,通常需要先将其转换为std::shared_ptr
。这可以通过调用std::weak_ptr::lock
方法实现,该方法会尝试获取一个指向对象的std::shared_ptr
。如果对象仍然存在,lock
方法会返回一个有效的std::shared_ptr
;否则,返回一个空的std::shared_ptr
。
下面是一个简单的示例,展示了如何使用 std::weak_ptr
来避免循环引用:
#include <iostream>
#include <memory>
class Parent;
class Child {
public:
std::weak_ptr<Parent> parent;
~Child() {
std::cout << "Child destroyed\n";
}
};
class Parent {
public:
std::shared_ptr<Child> child;
~Parent() {
std::cout << "Parent destroyed\n";
}
};
int main() {
{
auto parent = std::make_shared<Parent>();
auto child = std::make_shared<Child>();
parent->child = child;
child->parent = parent;
// 此时,parent 和 child 对象相互持有对方的引用,但由于 child 使用的是 weak_ptr,
// 因此不会造成循环引用。当离开这个作用域时,parent 和 child 都会被正确删除。
}
return 0;
}
在这个例子中,Parent
类持有一个指向 Child
的 std::shared_ptr
,而 Child
类持有一个指向 Parent
的 std::weak_ptr
。当 parent
和 child
对象离开作用域时,它们都会被正确删除,即使它们相互引用。这是因为 std::weak_ptr
不增加引用计数,所以不会阻止对象的删除。