Qt + C++编程问题系列1:解决因this指针被析构导致的崩溃问题<初识enable_shared_from_this类及使用智能指针的好处>

前言

在基于Qt和C++开发的程序运行的时候,程序突然发生崩溃,在查找原因的时候花费的时间比较多,情形一般情况遇不到,因此写篇博客记录一下。

原因

在Qt编程中,很多时候为了不让数据计算和处理占用主线程影响界面刷新(太多的东西占用主线程影响界面刷新速度就会导致卡顿这是我们不想看见的),因此都会将数据处理或者其他的一些事件转到线程中去处理。我在从主线程转线程时使用strand->post(boost::bind(&类名::函数名, this));这样的情况下,偶尔booost::bind绑定的对象会因为界面析构跟着析构掉,主线程析构掉了,但是转过去的线程并不知道这件事情,这个时候this指针就会变成野指针,导致程序崩溃。
this指针记录当前类的位置信息,在当前对象析构后,this指针也会跟着析构掉,如果此时有其他对象在使用这个指针,就会造成野指针崩溃。所以this指针是不可以记录是否有对象在使用的,这个时候就要想到智能指针。
智能指针有一个最大的优势就在于:每有一个对象在使用这个指针的时候他的引用计数就会增加1,每有一个对象不在使用的时候引用计数就会减少1。只有在引用计数为0的时候这个智能指针才会析构。这样就不会导致:还有对象在使用这个指针的时候,这个指针却析构掉了的问题。

解决办法

将this指针替换成指向对象本身的智能指针。当类本身被share_ptr(智能指针)管理,且在类本身的成员函数里需要把当前类对象作为参数传给其他函数时,就需要传递一个指向自身的share_ptr。
在实现上面的功能之前,得保证该类支持shared_from_this()函数,该函数封装在类enable_shared_from_this里面。这个时候就得让该类继承enable_shared_from_this类。
代码示例如下:
.h文件

class base;
typedef boost::shared_ptr<base> basePtr;

class base : public boost::enable_shared_from_this<base>
{
	public:
		base();
		~base();
	protected:
		basePtr self(); //能返回指向本身的智能指针
		void testFunc(); //测试函数

		boost::shared_ptr<boost::asio::strand>		m_strand;
}

.cpp文件

class base
{
	base::base()
	{
		"这里是构造函数!";
	}
	
	base::~base()
	{
		"这里是析构函数!";
	}

	basePtr base::self()
	{
		return boost::dynamic_pointer_cast<base>(shared_from_this());
	}

	void base::testFunc()
	{
		// threadFunc是需要转到线程的函数
		m_strand->post(boost::bind(&base::threadFunc, this)); //使用this指针的方法,如果base存在被析构的可能,不建议使用这种方法
		m_strand->post(boost::bind(&base::threadFunc, self())); //使用智能指针的方法
	}
}

boost和C++11

本文中我使用的boost里面的函数并没有使用C++11新特性,原因是我的工作环境还没有向C++11转换,所以采用的boost,如果大家已经开始使用C++11可以直接#include<memory.h>就可以了,其他的将boost::换成std::

结尾

本人是刚毕业参加工作小白一枚,写这篇文章只为记录一些自己在工作中遇到的一些值得记录的东西。
如果有些的不好的或者不正确的地方,请大家批评指正。
欢迎大家评论区和谐讨论!
附上自己很喜欢的一张壁纸(侵权联系我删除!!!
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值