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.pswp.cn/news/904138.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/904138.shtml
英文地址,請注明出處:http://en.pswp.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;特別是為了…