shared_ptr是如何实现的?
std::shared_ptr
是一个 C++ 智能指针,它是通过引用计数来实现的,能够多个指针对象共享所有权。具体来说,它包含两个主要的元素:
- 指向管理的实际对象的指针。
-
指向控制块(Control Block)的指针。这个控制块包含两个引用计数(一个用于
shared_ptr
,一个用于weak_ptr
)和管理对象的析构函数。
当你创建一个新的 shared_ptr
并使其指向一个对象,会创建一个新的控制块,并将 shared_ptr
的引用计数设为1。如果你创建了另一个 shared_ptr
并使其指向同一个对象(也就是复制构造或赋值),引用计数会增加。每当 shared_ptr
的一个实例被销毁(例如,它离开了其作用域),引用计数会减少。
当引用计数变为0,表示没有 shared_ptr
指向这个对象了,控制块就会自动调用析构函数并释放对象的内存。然后,控制块会检查 weak_ptr
的引用计数,如果也为0,就会销毁控制块。
std::shared_ptr
还有一个配套的 std::weak_ptr
类型,它也指向控制块,但是不会增加 shared_ptr
的引用计数。weak_ptr
的主要用途是防止 shared_ptr
的循环引用问题。
这是一个 std::shared_ptr
的简单示例:
#include <iostream>
#include <memory>
struct Foo {
Foo() { std::cout << "Foo::Foo\n"; }
~Foo() { std::cout << "Foo::~Foo\n"; }
};
void func() {
std::shared_ptr<Foo> sp1(new Foo); // shared_ptr reference counter is 1
std::cout << "sp1 use count: " << sp1.use_count() << '\n';
{
std::shared_ptr<Foo> sp2 = sp1; // shared_ptr reference counter is 2
std::cout << "sp1 use count: " << sp1.use_count() << '\n';
std::cout << "sp2 use count: " << sp2.use_count() << '\n';
} // sp2 is out of scope. shared_ptr reference counter becomes 1
std::cout << "sp1 use count: " << sp1.use_count() << '\n';
} // sp1 is out of scope. shared_ptr reference counter becomes 0, Foo object is deleted
int main() {
func();
return 0;
}
这个例子展示了如何使用 std::shared_ptr
,以及当 shared_ptr
的引用计数变为0时,对象是如何自动被删除的。