简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
1.前言
本篇目的:C++之weak_ptr与shared_ptr强弱智能指针用法
在C++中,weak_ptr和shared_ptr是智能指针的两种类型,用于解决资源管理和避免内存泄漏的问题。
-
shared_ptr(共享指针):
- shared_ptr允许多个智能指针共享同一个对象的所有权。
- 每个shared_ptr都维护一个引用计数,它记录有多少个shared_ptr指向同一对象。
- 只有当引用计数变为0时,shared_ptr才会自动析构并释放资源。
- 可以通过std::make_shared或std::shared_ptr构造函数来创建shared_ptr对象。
-
weak_ptr(弱指针):
- weak_ptr是一种不控制对象生命周期的智能指针,它指向一个由shared_ptr管理的对象。
- weak_ptr可以观测shared_ptr的生命周期,但不会增加引用计数。
- 使用lock()函数可以获取一个有效的shared_ptr对象来访问观测的资源。
- 如果shared_ptr已经释放了资源,则lock()函数会返回一个空的shared_ptr。
使用shared_ptr的好处:
- 避免内存泄漏:通过引用计数,当没有shared_ptr指向对象时,会自动进行资源释放。
- 安全共享对象:多个shared_ptr可以共享访问同一个对象,不会出现多次释放同一资源的问题。
使用weak_ptr的好处:
- 避免循环引用:当对象之间存在互相引用而没有外部引用时,使用weak_ptr作为其中一个引用可以打破循环引用,避免内存泄漏。
- 安全观测资源:通过lock()函数,可以安全地观测shared_ptr所管理的对象,避免悬空指针的问题。
需要注意的是,当使用weak_ptr时,需要注意判断返回的shared_ptr是否为空,以处理shared_ptr已释放资源的情况。另外,weak_ptr并不拥有指向的资源,因此不能直接通过weak_ptr访问资源的成员函数或成员变量,需要使用lock()函数获取shared_ptr对象后才能进行访问。
在C++中,std::weak_ptr
类提供了一个成员函数lock()
,用于获取与其关联的std::shared_ptr
对象。
lock()
函数的实现如下:
template<class T>
std::shared_ptr<T> std::weak_ptr<T>::lock() const noexcept;
lock()
函数的作用是尝试获取与std::weak_ptr
对象关联的std::shared_ptr
对象。如果关联的std::shared_ptr
对象仍然存在,lock()
函数会返回一个有效的、指向相同目标的std::shared_ptr
对象。如果关联的std::shared_ptr
已被销毁,lock()
函数将返回一个空指针(nullptr
)。
lock()
函数是线程安全的,并且在多线程环境中可以正确地处理std::shared_ptr
的引用计数和资源管理。
使用lock()
函数可以安全地访问由std::weak_ptr
进行观测的对象,避免了悬空指针的风险,同时也不会增加引用计数。
2.应用实例
#include <iostream>
#include <memory>
#include <string>using namespace std;class C2ComponentStore {
public:C2ComponentStore() {}~C2ComponentStore() {}string name = "123456789";
};int main() {//1.创建一个weak_ptr对象platformStore,初始为空std::weak_ptr<C2ComponentStore> platformStore;//2.通过lock()函数获取platformStore的shared_ptr对象std::shared_ptr<C2ComponentStore> store = platformStore.lock();//3.如果获取的shared_ptr对象为空if(store == nullptr) {//4.创建一个新的shared_ptr对象store,并使用make_shared初始化store = std::make_shared<C2ComponentStore>();//5.将store赋值给platformStoreplatformStore = store;}printf("store.name = %s\n",store->name.c_str());printf("platformStore.name = %s\n",platformStore.lock()->name.c_str());return 0;
}
以上代码中,platformStore.lock()
的调用将尝试获取与platformStore
关联的std::shared_ptr
对象。如果对象仍然有效,那么返回的std::shared_ptr
对象是有效的,可以使用它来访问对象的成员变量和方法。如果对象已被销毁,那么返回的std::shared_ptr
对象将是一个空指针。