Qt实现 hello world + 内存泄漏(5)

文章目录

  • 实现hello world的两种方式
    • 通过图形化的方式
    • 通过纯代码的方式
      • 1. 新老头文件的说明
      • 2.堆或栈上创建对象的选择
      • 3.QString的说明
  • 内存泄漏问题

实现hello world的两种方式

通过图形化的方式

通过图形化的方式,在界面上创建出一个控件,显示出hello world,双击widget.ui进入到Qt Designerlabel(标签)是界面上一个用来显示内容的字符串控件

在这里插入图片描述

下面图片在Qt Designer右上角处,通过树形结构显示出当前界面上有哪些控件

在这里插入图片描述

刚才往界面上拖拽了一个QLabel控件,可以通过下面图片看到,此时的widget.ui文件的xml中就自动的生成了一段代码,随后qmake就会在编译项目的时候基于这个内容去生成一段C++代码,通过这个C++代码就会去构建出界面内容,这些都是Qt工具自动生成的,无需手动操作

在这里插入图片描述

最终程序运行结果,以及程序运行成功后ui_widget.h文件内容的变动

在这里插入图片描述

通过纯代码的方式

通过纯代码的方式,通过编写代码,在界面上创建控件,显示hello world。这里要特别注意:;一般通过代码去构建界面的时候,通常会把构建界面的代码放到 Widget/MainWindow的构造函数中

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 构建界面的代码QLabel* label = new QLabel(this);label->setText("hello world");
}

1. 新老头文件的说明

若出现unkonwn type name ' QLabel',这就没有意味着没有包含头文件,因为Qt中每个类都有一个对应的头文件,而当我们去widget.h中输入头文件时会出现以下两个版本 QLabelqlabel.h,其中qlabel.h是Qt早期时候用的头文件,自1998年之后C++标准委员会成立了C++98标准,规定包含的头文件统一使用 #include<cstdio>代替原有的#include<stdio.h>,因此Qt的头文件也随之更新了

在这里插入图片描述

2.堆或栈上创建对象的选择

这里得在堆上创建对象,我在栈上创建对象,发现程序上显示不出 hello world ,这里我认为是栈和堆上对象的生命周期是不一样的,且堆上对象的生命周期通常比栈上对象长的缘故(此时的label对象随着构造函数的结束就销毁了)这里的QLabel(this)意思是给当前这个label对象指定一个父对象(widget w),这里牵扯到对象树,后面陈述

QLabel* label = new QLabel(this); // 这种是在堆上创建对象
QLabel label(this); // 这种是在栈上创建对象

3.QString的说明

label->setText(),意思是设置的控件中,要显示的文本是啥

在这里插入图片描述
这里出现了一个QString,咱记得C++中用的不是string吗?这个QString又是咋回事呢?这里又牵扯到了Qt的历史。

  • Qt诞生于1991年,那个时候C++还没有形成标准,那就更不用说C++有如今"标准库"这样的改变了,当时如何表示一个字符串有两种方式,可以使用C风格字符串(\0结尾),也可以使用C++的string。
  • 可是当年C++的string,C风格字符串 啥的都不太好用,那Qt 为了让自己的开发能变的顺畅,就自己发明了一套轮子,也就是搞了一系列的基础类来支持Qt的开发(包括不限于:字符串 QString,动态数组 QVector,链表 QList,字典 QMap等等)。
  • 那很多年之后,string,vector上述这些容器等内容,已经打磨的很好了,形成了C++标准,那这些已经引入的 Qt 自己包装好的这些容器类也不可能删了,也就只能和现有的标准库中的容器类共存了。
  • 因此,咱们开发 Qt代码的时候,如果需要用到上述容器类可以使用标准库的容器,也可以使用Qt自己搞的这一套,但是Qt原生的 api 中,涉及到的接口用的都是Qt 自己的这一套容器,后续的代码中还会经常见到QString这样的一些东西,但很少见到std::string
  • 不过QString和std::string 之间也能很方便的相互转换。而且QString 用起来要比 std::string好用很多,因为QString 内部已经对于字符编码做了处理了,而不像std::string就啥都没干
label->setText("hello world");

在QString中也提供了C风格字符串作为参数的构造函数,不显示构造Qstring,C风格字符串也会隐式构造成QString对象。这里不需要去包含QString对应的头文件,这是因为该头文件已经被很多Qt内置的其他类给间接包含了,所以无需再去显示包含QString头文件这里通过代码创建Qlabel,其字符串默认是放在左上角,想放到其它位置也是可以的(只不过我还没学到哈)

内存泄漏问题

仔细一看上述的代码会发现没有delete label,这将会造成内存泄漏,对于我们程序员来说,关注内存泄漏是要融入到DNA中的事情,这非常的重要!!!因为内存泄漏是个非常严重的事情(不仅仅是内存泄漏,包括文件描述符泄漏等同类问题都是非常严重的) 接下来看看我老师的自述(我认为是非常宝贵的经验

因为内存泄漏这种问题,不容易第一时间发现。我在搜狗的时候~~我要上线一个程序(把程序部署到生产环境上 此时这个程序就可以被外面的用户访问到,那如果生产环境挂了,用户就访问不了了,非常严重的事故!!)而对面的兄弟,想让我给他带一个版本到生产环境上去,这是因为上线是一个挺麻烦的事情(让测试进行测试,测试通过,预约运维同学排期,还需要提电子流 让领导层层审批)这种帮别人带代码上线,在当时是非常常见的,虽然操作是违规操作,但是还是会给人家带。
具体的上线操作也是非常繁琐的、当时我们有几十台服务器,就是要把程序部署到这几十台服务器上一般来说都是"灰度上线",先上线一台机器,观察一下,验证一下,看看这个机器更新版本之后,有没有问题,如果没问题,再上线后续的机器,如果有问题,那就赶紧调查问题,后续的机器上线就暂停,只上线一台机器,哪怕出现严重bug,影响面积不大,造成的后果/损失比较有限。
那天上午,我上线了一台机器,中午吃饭了开始午休~~到了下午的时候,已经观察几个小时了,我检查了一下这个上线的机器,发现没啥问题,各个功能,各个指标都正常(这里监控程序会去监测)给运维同学说可以上线后续机器了,这时候第一台机器狂报警!这意味着出事了,我就赶紧去查看机器,发现这个机器上的程序出现了"文件资源泄露"问题(可能是打开了文件,没有close)(每个进程=> pcb=>文件描述符表每次打开一个文件,都需要在文件描述符表中 申请一个表项,那文件描述符表长度是有上限的,而要花多长时间才能达到上限?不知道就看你的代码泄露速度快不快了)我就找到这个兄弟一起排查,他发现自己的代码中打开了文件没关闭(这里可能关闭了文件,但因为啥原因跳过了关闭文件)那如果泄露速度再慢点,一直到凌晨,夜深人静我们都在睡觉的时候突然搞出这么一手,那将面临着所有的机器都可能会瘫痪,整个业务线就直接没了。

先声明,上述代码在Qt中并不会产生内存泄漏的问题,label对象会在合适的时候被析构给释放掉(虽然并没有手动写析构,但确实能释放掉),那之所以能释放掉,主要是把这个对象挂在对象树上。之前通过new的方式在堆上创建对象并且指定父节点,就是为了把这个对象的生命周期交给Qt对象树来统一管理,这样对象树生命周期就是该对象的生命周期,那如果这个对象是按照栈上的变量创建的,那栈销毁了,该对象不仅没了吗?这就可能存在一些提前释放的问题

在这里插入图片描述

前端开发(网页开发)也涉及到类似的对象树(DOM),本质上也是一个树形结构(N叉树),这样通过树形结构就能把界面上的各种元素都组织起来,而Qt也是类似的,搞了一个N叉树,最主要的目的就是为了能构造在合适的时机(窗口关闭/销毁)把这些对象统一进行释放,而且通过这个树形结构把界面上要显示的这些控件对象都组织起来了那如果某个对象提前销毁了,此时就会导致对应的控件就在界面上不存在了,这也是为啥在栈上创建对象,运行起来的程序无法显示出hello world

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/904138.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【翻译、转载】【译文】模型上下文协议(Model Context Protocol, MCP)简介

原文地址&#xff1a; https://michaelwapp.medium.com/model-context-protocol-mcp-an-introduction-guide-25736f3dd672 在人工智能和 AI 驱动应用日新月异的格局中&#xff0c;一种与大型语言模型&#xff08;LLM&#xff09;交互的新方式正在兴起。随着 AI 智能体&#x…

[方法论]软件工程中的软件架构设计:从理论到实践的深度解析

文章目录 软件架构设计&#xff1a;从理论到实践的深度解析引言一、软件架构设计的核心目标体系1.1 质量属性矩阵1.2 架构权衡艺术 二、架构设计方法论演进2.1 传统设计范式2.2 现代架构方法论2.3 设计模式演化路径 三、主流架构风格全景图3.1 单体架构&#xff08;Monolithic&…

【win11 】win11 键盘测试

我的键盘是支持mac和win的&#xff0c;fn tab 就能切换&#xff0c;有可能是用错了模式&#xff0c;导致 我alt a 就会弹出 win11的 wifi 等菜单控制 键盘测试网站 https://keyboard.bmcx.com/ 识别到我按下的是alt

Linux环境部署iview-admin项目

环境&#xff1a;阿里云服务 系统&#xff1a;CentOS7.X系统 1、下载源码安装包 wget https://nodejs.org/dist/v14.17.3/node-v14.17.3-linux-x64.tar.xz2、解压并放入指定目录 tar -xf node-v14.17.3-linux-x64.tar.xz && mv node-v14.17.3-linux-x64 /usr/local/no…

VSCode常用插件推荐

文章目录 VSCode常用插件推荐1 Git相关插件2 代码格式3 AI工具4 语言插件通用工具参考 VSCode常用插件推荐 1 Git相关插件 2 代码格式 3 AI工具 4 语言插件 通用工具 参考 50 个 VSCode 必装插件推荐 https://mp.weixin.qq.com/s/b_OKvg3hdavtnv7pbWcKWg

【Unity】使用XLua进行热修复

准备工作&#xff1a; &#xff08;1&#xff09;将XLua的Tool拖入Asset &#xff08;2&#xff09;配置热修复 &#xff08;3&#xff09;运行Genrate Code &#xff08;4&#xff09;运行Hotfix Inject In Editor 编写脚本&#xff08;注意类上带有[Hotfix]&#xff09; [Hot…

javaEE——单例模式

目录 前言1.概念2. 实现3. 比较和改进总结 前言 本篇文章来介绍单例模式&#xff0c;并讲述在保证线程安全的前提下&#xff0c;单例模式的写法。 1.概念 单例模式是一种设计模式&#xff0c;可以说是写代码的一种模板&#xff0c;如果在一些固定的场景下按照设计模式进行写…

TS 对象类型

给对象添加类型注解 ![在这里插入图片描述(https://i-blog.csdnimg.cn/direct/6c413992c11142d88106633ec442b905.png) 格式&#xff1a;数据类型名:类型别名 注意&#xff1a;对象类型限制使用分号&#xff0c;如果对象中存在方法就写成&#xff1a;方法&#xff08;&#x…

C++类_虚基类

在 C 里&#xff0c;虚基类是用来解决菱形继承问题的。菱形继承问题是指当一个派生类从两个或更多基类派生&#xff0c;而这些基类又从同一个基类派生时&#xff0c;派生类会包含多份间接基类的数据副本&#xff0c;这可能会引发数据冗余和二义性问题。虚基类可以保证在派生类中…

详细案例,集成算法

以下是一个使用 随机森林&#xff08;RF&#xff09; 和 XGBoost 解决结构化数据分类问题的完整案例&#xff08;以泰坦尼克号生存预测为例&#xff09;&#xff0c;包含数据处理、建模和结果分析&#xff1a; 案例&#xff1a;泰坦尼克号乘客生存预测 目标&#xff1a;根据乘客…

《C#数据结构与算法》—201线性表

线性表的实现方式 顺序表 线性表的顺序存储是指在内存中用一块地址连续的空间依次存放线性表的数据元素&#xff0c;用这种方式存储的线性表叫顺序表。 特点&#xff1a;表中相邻的数据元素在内存中存储位置也相邻。 顺序表接口实现&#xff1a; 方法名参数返回值描述GetLen…

深入解析C++11委托构造函数:消除冗余初始化的利器

一、传统构造函数的痛点 在C11之前&#xff0c;当多个构造函数需要执行相同的初始化逻辑时&#xff0c;开发者往往面临两难选择&#xff1a; class DataProcessor {std::string dataPath;bool verbose;int bufferSize; public:// 基础版本DataProcessor(const std::string&am…

LeetCode 热题 100 189. 轮转数组

LeetCode 热题 100 | 189. 轮转数组 大家好&#xff0c;今天我们来解决一道经典的算法题——轮转数组。这道题在LeetCode上被标记为中等难度&#xff0c;要求我们将数组中的元素向右轮转 k 个位置。下面我将详细讲解解题思路&#xff0c;并附上Python代码实现。 问题描述 给定…

GAEA商业前景和生态系统扩展

GAEA情感坐标系不仅增强了AI对人类情感的理解&#xff0c;也为Web3生态注入了新的活力。通过去中心化的数据存储和共享&#xff0c;GAEA构建了一个开放透明的数据市场&#xff0c;为AI训练提供了优质的数据源。同时&#xff0c;贡献数据的用户将获得灵魂积分&#xff08;SOUL P…

[原创](现代Delphi 12指南):[macOS 64bit App开发]: [2]如何使用跨平台消息框?

[作者] 常用网名: 猪头三 出生日期: 1981.XX.XX 企鹅交流: 643439947 个人网站: 80x86汇编小站 编程生涯: 2001年~至今[共24年] 职业生涯: 22年 开发语言: C/C++、80x86ASM、Object Pascal、Objective-C、C#、R、Python、PHP、Perl、 开发工具: Visual Studio、Delphi、XCode、…

js逆向绕过指纹识别

​​一、兼容性说明​​ 官方支持 curl_cffi 明确支持 Windows 平台&#xff0c;并提供了预编译的安装包。其核心功能&#xff08;如浏览器指纹模拟、HTTP/2 支持&#xff09;在 Windows 上与 Linux/macOS 表现一致。 版本要求 • Python 3.8 及以上版本&#xff08;推荐 Pyth…

聊聊对Mysql的理解

目录 1、Sql介绍 1.1、SQL的分类 1.2、数据库的三大范式 1.3、数据表的约束 1.4、约束的添加与删除 2、核心特性 3、主要组件 4、数据结构原理 5、索引失效 6、常用问题 7、优势与局限 前言 MySQL是一个开源的关系型数据库管理系统(RDBMS)&#xff0c;由瑞典MySQL A…

[HOT 100] 1617. 统计子树中城市之间最大距离

文章目录 1. 题目链接2. 题目描述3. 题目示例4. 解题思路5. 题解代码6. 复杂度分析 1. 题目链接 1617. 统计子树中城市之间最大距离 - 力扣&#xff08;LeetCode&#xff09; 2. 题目描述 给你 n 个城市&#xff0c;编号为从 1 到 n 。同时给你一个大小为 n-1 的数组 edges &…

接口自动化——参数化

之前有说过&#xff0c;通过pytest测试框架标记参数化功能可以实现数据驱动测试。数据驱动测试使用的文件主要有以下类型&#xff1a; txt 文件 csv 文件excel 文件json 文件yaml 文件.... 本文主要讲的就是以上几种文件类型的读取和使用 一.txt 文件读取使用 首先创建一个 …

游戏引擎学习第257天:处理一些 Win32 相关的问题

设定今天的工作计划 今天我们本来是打算继续开发性能分析器&#xff08;Profiler&#xff09;&#xff0c;但在此之前&#xff0c;我们认为有一些问题应该先清理一下。虽然这类事情不是我们最关心的核心内容&#xff0c;但我们觉得现在是时候处理一下了&#xff0c;特别是为了…