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

2023-11-09

前言

在基于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::

结尾

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • 云计算学习总结

    云计算总结 理论汇总 与saas不同 基于平台服务的云计算形式把开发环境或者运行平台也作为一种服务给用户提供 云计算是对并行计算 网格计算 分布式计算技术的发展与运用 Amazon com公司通过EC2计算云 可以让客户通过webservi
  • WPF 折线图

    一 折线图 一 安装和查看值 1 需要联网安装 通过Nuget安装LiveCharts 搜索安装 2 想查看需要使用的值 点击对象管理器 查LiveCharts Wpf Series 里面有需要用的值 安装完成的效果 二 视图代码
  • List多字段升降序排序

    工具类 Component public class SortListUtil
  • 【Unity笔记】获得鼠标点击屏幕的位置,并转成世界坐标

    Vector3 pos Camera main ScreenToWorldPoint Input mousePosition
  • Win 10 设置右键以管理员方式打开 CMD 窗口

    Add Open Command Window Here as Administrator reg Windows Registry Editor Version 5 00 HKEY CLASSES ROOT Directory shell
  • [623]64位WIN10下安装.net20

    下载Microsoft NET Framework 2 0 软件开发工具包 SDK x64 地址 https www microsoft com zh CN download confirmation aspx id 15354 https
  • Ubuntu防火墙操作

    ubuntu默认提供了防火墙工具ufw 安装sudo apt get install ufw 检查防火墙的状态 sudo ufw status inactive 关闭 active 开启 关防火墙 sudo ufw disable 开防火墙
  • linux 全局查找文件命令

    find name xxx aaa
  • android bitmap面试题,Android面试Android进阶(十四)-Bitmap相关问题

    问 drawable和mipmap的区别是什么 答 根据官方说明 应用图标的图片资源存放在mipmap系列文件夹中 而其余图片存放在drawable系列文件夹中 1 mipmap纹理映射技术会将资源缩放到设备分辨率大小 drawable会将
  • Struts2框架xml验证

    struts2框架验证 xml方式 首先要从页面中获取对应的标签name属性的值 在动作类action中声明同名的属性 提供get和set方法 创建一个xml格式验证文件 命名方式 ActionClassName validation xm
  • vue2 + antd1.7.8 和 vue3 + antd2.2.8表单动态添加删除表单项

    1 vue2 antd 1
  • 英文投稿的一点经验【转载】

    英文投稿的一点经验 转载 1 首先一定要注意杂志的发表范围 超出范围的千万别投 要不就是浪费时间 另外 每个杂志都有他们的具体格式要求 一定要按照他们的要求把论文写好 免得浪费时间 前些时候 我的一个同事向一个著名的英文杂志投稿 由于格式问
  • 【Android App】实战项目之仿微信的私信和群聊App(附源码和演示视频 超详细必看)

    需要全部代码请点赞关注收藏后评论区留言私信 手机最开始用于通话 后来增加了短信功能 初步满足了人与人之间的沟通需求 然而短信只能发文字 于是出现了能够发图片的彩信 但不管短信还是彩信 资费都太贵了 令人惜墨如金 后来移动公司推出飞信 它支持
  • 不同设备屏幕尺寸和DPR适配

    为什么需要适配 目前市面上设备屏幕属性十分多样化 宽度和DPR并不一致 而作为设计和前端开发 无法为每个尺寸的设备单独设计一套UI并将其转为前端代码 这不现实 所以我们需要一套方案来将一套设计稿完美呈现在不同尺寸的设备上 设备的多样性不止体
  • Vue的双向绑定

    看过无数遍 还是说不清楚 来个说人话的加深印象 首先再vue初始化的时候 就对data数据进行了劫持监听 其中就是监听器 Observe 用来监听所有属性 若有属性发生变化就需要告诉订阅者Watcher看是否需要更新 因为订阅者Watche
  • [Matlab科学计算] 欧拉角和坐标变换个人总结

    问题由来 在计算铁磁材料多晶体的有效模量时 需要考虑晶粒在多晶体中的方向分布 一般用三个欧拉角来表示晶粒在多晶体中的方向 用方向分布函数来表示某个方向的分布密度 基于此 迫使我要掌握欧拉角 但是在阅读众多教材和博客文章中发现 大家对欧拉角的
  • JAVA对象在内存中运行机制

    在方法中创建一个对象时 在方法栈中只存有对象在堆中的地址 对象本身存放在堆内存中 类中的非static成员属于对象在堆中被创建 类中的static成员属于类并在运行类时存放在永生代中
  • PV、EV、AC、BAC、EAC、ETC等的含义及计算公式

    PV EV AC BAC EAC ETC等计算公式含义 PV Planned Value 计划值 应该完成多少工作 按照计划截止目前应该花费的预算 AC Actual Cost 实际成本 完成工作的实际成本是多少 截止目前实际的花费 EV
  • multiple definition of(变量或者函数)

    今天在公司写项目的时候 遇到如下错误 半个小时了 没看出来问题出在哪里 我看了好几遍代码 确认没有重定义 后来问旁边的大牛 才发现自己手误 错吧 include area h 写成 include area c 千万得小心啊 有时候心里想的
  • Qt + C++编程问题系列1:解决因this指针被析构导致的崩溃问题<初识enable_shared_from_this类及使用智能指针的好处>

    这里是目录 前言 原因 解决办法 boost和C 11 结尾 前言 在基于Qt和C 开发的程序运行的时候 程序突然发生崩溃 在查找原因的时候花费的时间比较多 情形一般情况遇不到 因此写篇博客记录一下 原因 在Qt编程中 很多时候为了不让数据