詳解 Qt PIMPL模式
詳解 Qt PIMPL模式是本文將要介紹的內容,不多說了,先來看內容。進行跨平臺的移植工作,這其中有些地方是無法完全移植過來的,所以:需要我們封裝一個接口類,在不同平臺下讓其有不同的實現。要做到這一點:有很多辦法,條件編譯啊之類的。但是如果有這種方法,說白了:其還是兩份代碼,僅僅是放到同一個文件中。參考Qt實現跨平臺的辦法,正好讀了一片這方面的文章,發現 PIMPL模式還是很適用的。
- //public.h
- Class PrivateClass //前置聲明
- Class PublicA:
- {
- Public:
- PublicA(); //如果私有實現類要調用位于公共類中的方法,則將該公共類指針傳給私有類構造函數
- ~PublicA();
- Private:
- PrivateClass* iPoint; //含有私有實現類的一個指針
- Private:
- Friend class PrivateClass; //如果私有實現類要調用公開類的方法,則將之聲明為友類。
- }
- //public.cpp
- #include "public.h"
- #ifdef Q_OS_SYMBIAN
- #include "PrivateClass_symbian.h"
- #else
- #include "PrivateClass_win32.h"
- #endif
- PublicA::PublicA()
- {
- #ifdef Q_OS_SYMBIAN iPoint = PrivateClass::NewL(this);
- #else
- iPoint= new PrivateClass( this );
- #endif
- }
如上:PIMPL是設計了對外公共類和私有實現類。 亦即:多個平臺對外的接口都是***的這個對外公共類,而不同平臺都有自己的私有實現類 。
為了做到這一點,需要如下做:
1、在頭文件中:
(1)聲明一下私有類(不是include)
(2)含有該私有類的一個指針數據成員。
2、在cpp實現文件中:
(1)用條件編譯的方式決定到底include哪個私有實現類的頭文件。
(2)在對外公共類的函數實現中:也用條件編譯的方法決定調用哪一個私有實現類的函數。
為了實現這一點,要求:各個私有實現類的類名必須一樣!(文件名可以不一致)
以上是一個最簡單的模型,當然:如果私有實現類中想調用對外公共類的函數,則需要在公共類中做兩件事:
1、在其創建私有類時:通過參數的方式將自己的指針傳入到私有類中,從而讓私有類含有公共類的指針。
2、在公共類中將私有類聲明為:友元類。 (這樣擴大了私有類的訪問權限,這個可以依據實際情況來確定需要不需要)
事實上:這正是Qt用來對底層操作系統進行抽象的解決辦法,它使開發者無需關心每一個平臺的底層編程方法和各種限制。
針對qt開發而言:一般這些私有實現類都是針對不同平臺的,比如:symbian的一些系同級的函數,還有一些win特有的函數,這些都是無法做到跨平臺的,我們可以用PIMPL模式來進行抽象。此時上邊所說的條件編譯宏就是:不同平臺的宏了。同樣:還需要在pro中把針對不同平臺的私有實現文件放到平臺關鍵字中。
通常,如果公共類名為QMyClass ,那么:
私有類就被定義為QMyClassPrivate。
公共類的源文件和頭文件共享公共類名: qmyclass.h , qmyclass.cpp 。
私有類的頭文件和源文件名以 _p 結尾(比如 qmyclass_p.h ),除非該文件是一個平臺特定實現。
平臺特定實現的頭文件和源文件名中包括平臺名 – 如 qmyclass_symbian.cpp (不必在結尾處添加 _p ,因為已經暗示)。
小結:詳解 Qt PIMPL模式 的內容介紹完了,希望本文對你有所幫助!