1 share_ptr引用
std::shared_ptr是 C++11 及以后版本中提供的智能指针类型之一,它允许多个
std::shared_ptr对象共享所有权(ownership)的一个对象。当没有任何
std::shared_ptr` 对象指向该对象时,该对象将被自动删除。
与裸指针(raw pointer)相比,std::shared_ptr
的优点在于它可以自动管理对象的生命周期,从而减少内存泄漏和其它资源管理上的问题。
以下是关于 std::shared_ptr
的一些基本概念:
-
引用计数:
std::shared_ptr
使用引用计数来跟踪有多少个std::shared_ptr
实例指向同一个对象。当你创建一个新的std::shared_ptr
以共享一个已有的对象时,引用计数会增加。当std::shared_ptr
被销毁时,引用计数会减少。当引用计数变为 0 时,它指向的对象也会被销毁。 -
make_shared:这是创建
std::shared_ptr
的推荐方法,它在一个内存分配中同时创建对象和控制块(包含引用计数等信息)。这可以比单独为对象和控制块分配内存更为高效。
std::shared_ptr<int> p = std::make_shared<int>(42);
- 赋值和拷贝:你可以安全地将一个
std::shared_ptr
赋给另一个。这样,两者都会指向同一个对象,且引用计数会适当增加。
std::shared_ptr<int> p1 = std::make_shared<int>(42);
std::shared_ptr<int> p2 = p1; // Both p1 and p2 now point to 42, reference count is 2
-
用于数组:虽然
std::shared_ptr
可以用于数组,但推荐使用std::vector
或其他容器来管理动态数组。 -
循环引用:这是
std::shared_ptr
的一个潜在陷阱。如果你有两个对象,它们互相持有对方的std::shared_ptr
,那么这两个对象永远不会被删除,因为它们的引用计数永远不会达到0。为了解决这个问题,C++ 提供了std::weak_ptr
,它是一个不增加引用计数的智能指针,常与std::shared_ptr
一同使用来避免循环引用。
最后,建议深入学习相关的文档和例子,实践一些小程序以帮助你更好地理解和使用 std::shared_ptr
。
#################
当然可以。以下是一个简单的程序,演示了 std::shared_ptr
的引用计数的变化:
#include <iostream>
#include <memory>
int main() {
// 创建 shared_ptr
std::shared_ptr<int> sp1 = std::make_shared<int>(10);
std::cout << "sp1 reference count: " << sp1.use_count() << std::endl; // 输出:1
// 创建一个 shared_ptr 并复制给 sp2
std::shared_ptr<int> sp2 = sp1;
std::cout << "sp1 reference count after assigning to sp2: " << sp1.use_count() << std::endl; // 输出:2
std::cout << "sp2 reference count: " << sp2.use_count() << std::endl; // 输出:2
// 创建一个新的 shared_ptr 并赋值给 sp3
std::shared_ptr<int> sp3;
sp3 = sp1;
std::cout << "sp1 reference count after assigning to sp3: " << sp1.use_count() << std::endl; // 输出:3
// 重置 sp2,断开与原对象的关联
sp2.reset();
std::cout << "sp1 reference count after sp2 reset: " << sp1.use_count() << std::endl; // 输出:2
// sp3 离开其作用域
{
std::shared_ptr<int> sp3_local = sp1;
std::cout << "sp1 reference count inside scope: " << sp1.use_count() << std::endl; // 输出:3
}
std::cout << "sp1 reference count after scope: " << sp1.use_count() << std::endl; // 输出:2
return 0;
}
在这个程序中,我们多次输出了引用计数,以便观察不同操作(如赋值、重置、离开作用域等)对引用计数的影响。
2 share_ptr中的重置
当你对一个 std::shared_ptr
调用 reset()
方法后,这个 shared_ptr
将不再指向之前的对象(如果之前有的话)。更具体地说,sp2
将成为一个空的 shared_ptr
,它不指向任何对象。
如果你尝试解引用一个已经被 reset()
的 shared_ptr
,程序将引发运行时错误。
在你给出的示例中,调用 sp2.reset()
后,sp2
将不再指向之前的整数对象。如果你检查 sp2
是否指向一个对象,结果将为 false
:
if (