在C++中,std::shared_ptr
是智能指针的一种,它用于自动管理具有动态生命周期的对象。当std::shared_ptr
的实例被销毁或重置时,它所指向的对象(如果仍然存在)将被自动删除(调用delete
),前提是这是最后一个指向该对象的std::shared_ptr
实例。std::shared_ptr
实现了所谓的“共享所有权”模式,允许多个std::shared_ptr
实例共同拥有同一个对象。
主要特性
- 自动内存管理:当没有任何
std::shared_ptr
指向一个对象时,该对象会被自动删除,从而避免了内存泄漏。 - 共享所有权:多个
std::shared_ptr
可以指向同一个对象,每个std::shared_ptr
的实例都会维护一个内部计数器(通常称为“控制块”),该计数器表示有多少个std::shared_ptr
实例正在指向该对象。 - 安全拷贝和赋值:当你拷贝或赋值一个
std::shared_ptr
时,内部计数器会增加,从而确保对象在拷贝或赋值后仍然被正确管理。 - 弱引用:通过
std::weak_ptr
,可以实现对std::shared_ptr
所管理对象的非拥有性观察,即不会增加内部计数器的值。这有助于解决循环引用问题。
基本用法
#include <memory>
#include <iostream>
class Example {
public:
Example() { std::cout << "Example created\n"; }
~Example() { std::cout << "Example destroyed\n"; }
void sayHello() { std::cout << "Hello from Example\n"; }
};
int main() {
// 创建一个指向Example的shared_ptr
std::shared_ptr<Example> ptr1 = std::make_shared<Example>();
// 拷贝ptr1到ptr2,两个shared_ptr都拥有对象
std::shared_ptr<Example> ptr2 = ptr1;
// 访问对象
ptr1->sayHello();
// 当ptr1和ptr2都离开作用域时,Example对象会被自动删除
return 0;
}
注意事项
- 循环引用:如果两个
std::shared_ptr
相互指向对方,它们将永远不会被销毁,因为每个std::shared_ptr
都认为对方还在使用其管理的对象。这可以通过引入std::weak_ptr
来解决。 - 性能:虽然
std::shared_ptr
提供了方便的内存管理,但相比于原始指针,它在性能上可能会稍差一些,因为它需要维护额外的控制块和进行原子操作。 - 线程安全:
std::shared_ptr
的拷贝和赋值是线程安全的,但如果你同时从多个线程访问它所管理的对象,则需要确保该对象的访问本身是线程安全的。