智能指针是C++标准库提供的一种RAII(资源获取即初始化)类型,用于自动管理动态内存的生命周期,以避免内存泄漏和悬挂指针等问题。智能指针主要包括std::unique_ptr
、std::shared_ptr
和std::weak_ptr
。以下是对这些智能指针的详细介绍以及如何使用它们。
1. std::unique_ptr
基本概念
通过这些智能指针,可以更安全、方便地管理动态分配的内存,减少内存泄漏和悬挂指针等问题。
- 唯一所有权:
std::unique_ptr
独占其所管理的对象,不能被复制,但可以移动。 - 自动释放:当
std::unique_ptr
超出作用域时,它会自动释放所管理的对象 -
#include <iostream> #include <memory> struct MyStruct { int data; MyStruct(int val) : data(val) { std::cout << "MyStruct constructed with value: " << data << std::endl; } ~MyStruct() { std::cout << "MyStruct destructed with value: " << data << std::endl; } }; int main() { // 创建std::unique_ptr管理的MyStruct实例 std::unique_ptr<MyStruct> ptr = std::make_unique<MyStruct>(42); std::cout << "Data in MyStruct: " << ptr->data << std::endl; // 转移所有权 std::unique_ptr<MyStruct> ptr2 = std::move(ptr); if (!ptr) { std::cout << "ptr is now nullptr" << std::endl; } std::cout << "Data in MyStruct through ptr2: " << ptr2->data << std::endl; // 自动释放内存 return 0; }
输出
-
MyStruct constructed with value: 42 Data in MyStruct: 42 ptr is now nullptr Data in MyStruct through ptr2: 42 MyStruct destructed with value: 42
2.
std::shared_ptr
基本概念
- 共享所有权:多个
std::shared_ptr
可以共享同一个对象,当最后一个std::shared_ptr
被销毁时,才会释放对象。 - 引用计数:
std::shared_ptr
内部维护一个引用计数,以跟踪有多少个shared_ptr
共享同一个对象。 -
#include <iostream> #include <memory> struct MyStruct { int data; MyStruct(int val) : data(val) { std::cout << "MyStruct constructed with value: " << data << std::endl; } ~MyStruct() { std::cout << "MyStruct destructed with value: " << data << std::endl; } }; int main() { // 创建std::shared_ptr管理的MyStruct实例 std::shared_ptr<MyStruct> ptr1 = std::make_shared<MyStruct>(42); std::cout << "Data in MyStruct: " << ptr1->data << std::endl; std::cout << "Reference count: " << ptr1.use_count() << std::endl; { std::shared_ptr<MyStruct> ptr2 = ptr1; // 共享所有权 std::cout << "Reference count after ptr2 creation: " << ptr1.use_count() << std::endl; } // ptr2超出作用域 std::cout << "Reference count after ptr2 is out of scope: " << ptr1.use_count() << std::endl; // 自动释放内存 return 0; }
输出:
-
MyStruct constructed with value: 42 Data in MyStruct: 42 Reference count: 1 Reference count after ptr2 creation: 2 Reference count after ptr2 is out of scope: 1 MyStruct destructed with value: 42
3.
std::weak_ptr
基本概念
- 弱引用:
std::weak_ptr
不影响对象的引用计数,用于解决std::shared_ptr
的循环引用问题。 - 升级到
std::shared_ptr
:可以通过lock
方法将std::weak_ptr
升级为std::shared_ptr
,前提是对象仍然存在。 -
#include <iostream> #include <memory> struct B; // 前向声明 struct A { std::shared_ptr<B> b_ptr; ~A() { std::cout << "A is destroyed" << std::endl; } }; struct B { std::weak_ptr<A> a_ptr; // 使用std::weak_ptr避免循环引用 ~B() { std::cout << "B is destroyed" << std::endl; } }; int main() { std::shared_ptr<A> a = std::make_shared<A>(); std::shared_ptr<B> b = std::make_shared<B>(); a->b_ptr = b; b->a_ptr = a; return 0; }
输出:
-
A is destroyed B is destroyed
在这个例子中,
std::weak_ptr
避免了std::shared_ptr
之间的循环引用,确保了对象能够正确地被销毁。总结
std::unique_ptr
:适用于独占所有权的场景,可以通过std::move
转移所有权。std::shared_ptr
:适用于共享所有权的场景,自动管理引用计数。std::weak_ptr
:用于解决std::shared_ptr
的循环引用问题,不影响对象的生命周期。