在講qt的d指標之前讓我們來簡單的解釋一下d指標出現的目的,目的是什麼呢?保證模組間的二進位制相容。
什麼是二進位制相容呢,簡單說就是如果自己的程式使用了第三方模組,二進位制相容可以保證在修改了第三方模組之後,也就是已經改變了記憶體布局之後,自己的程式可以不用重新編譯就能夠相容修改後的第三方模組。二進位制指的是編譯生成的.so或者dll庫,一旦程式編譯好之後類的記憶體布局就確定了,相容性值得就是即使記憶體布局被改變也依然能夠通過原來的記憶體布局找到對應的成員變數,比較官方的解釋是:
二進位制相容:在公升級庫檔案的時候,不必重新編譯使用此庫的可執行檔案或其他庫檔案,並且程式的功能不被破壞。一些詳細的介紹可以參考這個博文。
馬斯克為什麼這麼厲害,我記得在乙個採訪中他提到了為什麼自己這麼牛逼,什麼事情都敢幹,回答是因為自己堅信第一性原理這個理論。簡單闡述就是:
如果一件事從理論上是可行的,那就可以去幹那我們得到啟發之後回到這個問題本身,已經有了對二進位制相容的定義,我們根據上面的分析得出結論,用指標的方式實現不就可以規避二進位制不相容的情況了嗎?我們先動手嘗試完成乙個自己腦子裡的第一版實現:
1處的**可以直接設定q指標的方式比較優雅,不然我們要修改widgetprivate(widget* widget): q_ptr(widget){}
為這樣的建構函式,使用的時候
widget():d_ptr(new widgetprivate(this))
,顯然這種方式不夠優雅。這樣的話classprivate類就看著非常乾淨,甚至把class替換成struct都可以~
總的來說看起來很完美,widgetprivate
作為私有類我們在改動的時候並不會破壞widget
的二進位制相容性。然後呢,夠了嗎?我們知道qt的gui類是物件樹的結構,存在著多層次繼承結構(qobject<-qwidget<-qlabel ...),也在此基礎上實現了記憶體半自動化管理的機制。我們如果加乙個子類呢?動手試試
此版本包含幾個修改點:
公開類新增乙個protected級別的建構函式,用於子類構造的時候在初始化引數列表來初始化基類,這裡實現了多型的特性。
公開類的子類建構函式的初始化引數列表不再初始化d_ptr,而是呼叫基類的帶參建構函式,實參為*new labelprivate,跟[1]配合實現了多型性。
d指標轉換成子型別的私有類才都呼叫相關的方法。
label子類也要實現乙個protected保護級別的建構函式,因為label也可能會被繼承。
widgetprivate.h私有基類的析構函式定義為virtual,這樣在釋放資源的時候才能夠不漏掉labelprivate的釋放。
labelprivate繼承widgetprivate,構成多型的基礎條件。
ok,到這裡就基本完成了,可以不做修改的替換掉qt的那一套d指標和q指標,哈哈哈(有點扯了。)論實用程度是夠了,但是論優雅程度跟qt原生的還是有一定距離,我們新增一些語法糖和c++11的智慧型指標來優化一下。
手把手入門C語言 C語言指標
指標的長度 指標初步練習 指標的賦值練習 加深指標的理解 總 1 指標用於存放位址 2 列印值 p 3 加深理解指標實驗 p 123 指標的長度 列印各種指標的長度,所有指標的長度為4個位元組 include include 指標的長度 是4個位元組 能夠傳任何型別的位址 main 四個小實驗 in...
C 內部類和外部類的互相訪問(d指標和q指標)
d指標和q指標式qt中常見的封裝方法,由此引出了c 內部類和外部類的互相訪問。其實也是pimpl pointer to implementation,指向實現的指標 方法。實驗 inner類為outter類的私有內部類。inner類中有乙個public字串變數in,outter類中有乙個privat...
C語言 指標高階 《手把手教你學C語言》
3.多級指標 3.2通過指標引用二維陣列 4.函式指標 對於普通的陣列,其一大缺點就一旦定義以後就無法改變其大小容量。這其實本質上是靜態記憶體的缺陷。靜態記憶體 對於系統分配的記憶體就是靜態記憶體也叫棧記憶體,比如定義的變數,函式等等都是由系統進行記憶體的分配。因而程式設計師自己無法靈活對其進行更改...