<七>智能指针之__强弱指针使用场景之 多线程访问共享对象问题

文章讨论了C++中智能指针shared_ptr和weak_ptr在处理多线程内存管理时的作用。通过一个代码示例展示了当主线程删除对象后,子线程继续使用该对象导致的问题,并提出了解决方案——使用weak_ptr来检查对象的有效性,防止访问已被删除的对象。此外,解释了shared_ptr作为资源的共享所有权和weak_ptr作为弱引用避免循环引用导致的内存泄漏问题。
摘要由CSDN通过智能技术生成

问题场景代码1

#include <iostream>
#include <thread>
using namespace std;


class A {

public:
	A()  { cout  << "A()"  << endl; }
	~A() { cout  << "~A()" << endl; }
	void funcA() {
		cout << "A function()" << endl;
	}
};

void  thread_Handler(A  *pa) {

	std::this_thread::sleep_for(std::chrono::seconds(2));
	pa->funcA();

}

int main() {

	A *pa = new A();

	thread t1(thread_Handler, pa);

	delete pa;

	t1.join();

	return 0;
}

上面代码的问题:
std::this_thread::sleep_for(std::chrono::seconds(2));
后 pa指针已经main 线程中delete 掉了,删掉之后在访问 funcA()函数是不合理的
应该修改为

void  thread_Handler(A  *pa) {

	std::this_thread::sleep_for(std::chrono::seconds(2));
        if(pa所指向的对象是否还有效)
        {
           pa->funcA();
        }
}

//针对上面的场景,我们可以使用强弱智能指针,修改如下

代码2

#include <iostream>
#include <thread>
using namespace std;

class A {

public:
	A()  { cout  << "A()"  << endl; }
	~A() { cout  << "~A()" << endl; }
	void funcA() {
		cout << "A function()" << endl;
	}
};

void  thread_Handler(weak_ptr<A>  pa) {

	std::this_thread::sleep_for(std::chrono::seconds(2));
	shared_ptr<A> ptr = pa.lock();
	if (ptr == nullptr) {
		cout << "对象已经销毁了" << endl;
	}
	else {
		ptr->funcA();
	}
}

int main() {

	{
		shared_ptr<A> ptr(new A());

		thread t1(thread_Handler, weak_ptr<A>(ptr));
	
		t1.detach();
	}

	std::this_thread::sleep_for(std::chrono::seconds(10));
	return 0;
}

在这里插入图片描述

小结智能指针

share_ptr
share_ptr是C++11新添加的智能指针,它限定的资源可以被多个指针共享。

只有指向动态分配的对象的指针才能交给 shared_ptr 对象托管。将指向普通局部变量、全局变量的指针交给 shared_ptr 托管,编译时不会有问题,但程序运行时会出错,因为不能析构一个并没有指向动态分配的内存空间的指针

weak_ptr
weak_ptr是一种用于解决shared_ptr相互引用时产生死锁问题的智能指针。如果有两个shared_ptr相互引用,那么这两个shared_ptr指针的引用计数永远不会下降为0,资源永远不会释放。weak_ptr是对对象的一种弱引用,它不会增加对象的use_count,weak_ptr和shared_ptr可以相互转化,shared_ptr可以直接赋值给weak_ptr,weak_ptr也可以通过调用lock函数来获得shared_ptr。

weak_ptr指针通常不单独使用,只能和 shared_ptr 类型指针搭配使用。将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放。即使有weak_ptr指向对象,对象也还是会被释放。
weak_ptr并没有重载operator->和operator *操作符,因此不可直接通过weak_ptr使用对象,典型的用法是调用其lock函数来获得shared_ptr示例,进而访问原始对象。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值