使用qt2年多了,但是還是覺得很陌生,總是會被qt搞的很緊張,有時候當我自信滿滿的開啟幫助文件,搜尋某個已知的類時,由於筆誤敲錯了乙個字母而出現了另外乙個類,不過奇怪的是還真有這麼乙個類,哎!!!我怎麼都不知道呢!看來qt的東西還真不是一般的多,隨便乙個筆誤都可能發現新的東西。特別是qt現在已經發布了qt5.7版本,相對於qt4的時代那真是天差地別,就我個人而言,我現在用的是qt5.6.1-1,因為qt5.6版本官方聲稱維護2年的時間。qt5.6取消了webkit模組,如果需要使用可以自行編譯,我自己也對qt5.6.1-1的整個模組進行了編譯,有需要的小夥伴可以參考msvc2013編譯qt5.6原始碼 優點
缺點qt
1、龐大的**容易管理
2、成員的私有實現和具體對外開放的介面分離
1、閱讀性差
2、可擴充套件性差
表1 qt優缺點
上述缺點都是我個人認為,其中可擴充套件性差不是說qt不能擴充套件,而是擴充套件的時候有一定限制,因為qt的乙個功能實現的最基本單元就是filename.h、filename.cpp和filename_p.h,通常情況下我們只能拿到filename.h,而私有的filename_p.h檔案拿不到,所以不能進行對齊進行擴充套件,這也導致了一些操作不能很好的而進行,除非qt原始碼給我們了相關介面,否則我們是很難去維護私有的filename_p.h的實現,比如:qt的qcharts模組,這個模組是qt5.7才正式開源的模組,當然了有興趣的同學可以自己手動在自己的當前qt模組下編譯qtcharts,然後將開發所需要的庫都加入到自己當前的qt版本中。
為什麼說提到qcharts模組呢,是因為我之前看過大概的實現原理,他也是一貫的qt**作風,那就是不容易閱讀,每乙個對外暴露的介面,僅僅是介面而已,而他具體的實現都是隱藏在另外乙個沒有暴露給使用者的介面裡,如下圖1所示,qbarseries是對外開放的介面,但是其具體實現是在barseries內完成的,這樣就導致了我們只能對qbarseries進行重寫,而不能修改barseries類,或者對齊進行重寫。
圖1 qbarseries幫助文件
呵呵呵。。。說的有些多了,可能喜歡qt的人會來罵我,以上完全是我個人的理解,有不對的地方請指正。其實我個人還是挺喜歡qt的,最起碼在封裝上我覺得很好,介面的命名上也很容易理解,比較容易上手,對於乙個做c++介面工作的開發來說,算是乙個不錯的選擇。
下面進入本片文章的主題,本片文章我主要是想分析下qt的私有實現結構,其實也就是我們所謂的impl實現原則。
說起qt的**管理,我覺著真的非常好,畢竟是第乙個龐大的庫,如果沒有乙個優秀的**結構,對於c++這樣編譯性的語言,那真的是乙個噩夢,多麼優秀的程式設計師可能一天就處於編譯**的等待中。。。
qt在類的管理上,講成員函式單獨封裝到了乙個對於的_p.h的標頭檔案中,然後可能還是提供相應的私有介面,為什麼說私有呢,因為我們拿不到,但是qt的類中卻可以拿到,這個在下一節中我會做一些簡單的分析。
qt**分工:filename.h、filename.cpp和filename_p.h,而這3個檔案是用一組巨集類關聯起來,並使用,有一定的封裝性。後續文章中,filename.h中的類我就用class描述,filename_p.h中的類我就用classprivate描述。
1、q_declare_public
這個巨集是用來在filename_p.h類中使用得,為的就是可以拿到乙個class的類的乙個指標,並且它是class的友元類,class類是乙個泛指,指的是filename.h縱的類。
1#define q_declare_public(class) \
2 inline class* q_func() \
3 inline const class* q_func() const \
4 friend class class;
2、q_declare_private
這個巨集是在filename.h類中使用,和q_declare_public巨集是對於的,它是classprivate類的友元,並且可以拿到乙個classprivate的指標
1#define q_declare_private(class) \
2 inline class##private* d_func() \
3 inline const class##private* d_func() const \
4 friend class class##private;
3、q_d和q_q
這兩個巨集就比較好理解了,僅僅是快捷的拿到乙個指標,關於這個指標是怎麼宣告?在哪兒宣告?後續都會提到
1#define q_d(class) class##private * const d = d_func()2
#define q_q(class) class * const q = q_func()
首先我先來回答一下,第三節中第三小節所提到的問題,關於class和classprivate這兩個指標儲存的地方,就是他們分別的功能基類,而且必須是保護或者是公有成員。在後續的子類中都不需要再宣告該類指標
作為父類都必須提供至少兩個建構函式,乙個是用來宣告物件自己的,乙個是用來初始化子類的,這樣說可能會有點兒不好理解,那麼我就把qwidget的原始碼搬上來做以說明
圖1 qwidget公有建構函式
圖2 qwidget保護建構函式
圖1和圖2分別是qwidget的兩個建構函式,只是訪問許可權不一樣,保護函式只能在子類中訪問,那麼同學們是不是有些明白了,基類的classprivate就是通過這個保護的構造方法類初始化,子類傳遞給父類的classprivate指標,能賦值給父類的成員指標,那麼這個指標肯定有父子關係的,那麼又乙個關鍵點浮出水面,那就是classprivate也是可以繼承的,這樣很好的達到了私有資料繼承的問題,如圖3就是呼叫了子類的私有結構來初始化父類私有結構
圖3 子類建構函式
零散的說了這麼多,qt二進位制相容性也說了個大概,只是沒有系統的demo,那麼下面我貼乙個完整的測試頭資料夾,關於demo,後續我會給乙個完整的
1struct
basicplotprivate;
2 //基類 儲存私有結構指標 並提供乙個保護的建構函式
3class basicplot : public
qwidget
4 , public
plotcallback5;
20 //基類的私有結構 儲存乙個基類指標
21struct
basicplotprivate22;
27 //子類 不需要宣告指標 公有建構函式實現類似於圖3
28class financialplot : public
basicplot29;
42 //子類私有結構 繼承與父類私有結構
43struct financialplotprivate : public
basicplotprivate
4446
q_declare_public(financialplot)
47 };
補充:基於qcustomplot2.0.0的二次開發
二進位制 二進位制起源
現代通訊技術的基礎是二進位制編碼。早在1865年麥克斯韋總結出麥克斯韋方程組之前,美國人摩斯 morse 於1837年發明了摩斯電碼和有線電報。有線電報的出現,具有劃時代的意義 它讓人類獲得了一種全新的資訊傳遞方式,這種方式 看不見 摸不著 聽不到 完全不同於以往的信件 旗語 號角 烽火,這也是二進...
zabbix之二進位制安裝
參考官方 安裝apt源 安裝zabbix和zabbix前段 root ubuntu apt install zabbix server mysql root ubuntu apt install zabbix frontend php 在mysql伺服器安裝mysql root ubuntu apt...
MySQL之二進位制日誌
一 binlog日誌格式 根據日誌定義的格式不一樣,可以分為statement格式 row格式或者mixed格式 mysql5.6 binlog format statement mysql5.7 binlog format row 理解三種不同的格式 a statement格式 說明 基於語句的,...