C++詳解PIMPL指向?qū)崿F(xiàn)的指針
二進(jìn)制兼容性
①.概述
二進(jìn)制兼容是指當(dāng)庫文件升級(jí)后所有使用該庫的應(yīng)用程序不必重新編譯,其本質(zhì)就是類的內(nèi)存布局不變。使用 pimpl 方法設(shè)計(jì)類可以實(shí)現(xiàn)二進(jìn)制兼容的目的。
②.類成員更改后的內(nèi)存布局
原始類定義:
class demoClass { private: int a; int b; };
類更改后的定義:
class demoClass { private: char c; int a; int b; };
②.pimpl 下類的內(nèi)存布局
class demoClass { private: class demoClassImpl; demoClassImpl* impl; }; class demoClass::demoClassImpl { public: int a; int b; };
如上圖所示,無論類的實(shí)現(xiàn)類的數(shù)據(jù)成員如何變化,類的布局始終不變。
功能實(shí)現(xiàn)細(xì)節(jié)隱藏
①.概述
作為接口的提供者,我們希望接口的使用者不必知道接口實(shí)現(xiàn)的更多細(xì)節(jié),因?yàn)楦鶕?jù)類的私有數(shù)據(jù)成員和方法一般就可以猜測(cè)出接口的設(shè)計(jì)方式。
②.隱藏實(shí)現(xiàn)細(xì)節(jié)
通過 pimp 方法設(shè)計(jì)類可以實(shí)現(xiàn)隱藏類的私有成員和方法的目的,僅對(duì)外暴露公有的接口。
class demoClass { public: void func();//對(duì)外接口 private: class demoClassImpl; demoClassImpl* impl; }; class demoClass::demoClassImpl { private: int a; int b; void func1(); void func2(); public: void func(); }; void demoClass::func() { impl->func(); }
編譯依賴
①.概述
在一個(gè)常用的頭文件中如果包含了太多其他不必要的頭文件會(huì)嚴(yán)重降低編譯效率。
②.值類型的成員必須引用其頭文件
值類型的成員因?yàn)橐峙鋬?nèi)存大小必須知道其確定的定義,需要包含其頭文件
#include "A.h" class demoClass { A a; };
如果僅有類的申明則會(huì)出錯(cuò):
class A; class demoClass { A a; };
③.指針或者引用類型,僅需要類的申明
class A; class demoClass { A *a; };
④.函數(shù)的參數(shù)和返回值類型,僅需要類的申明
class A; class demoClass { A func(A a); };
⑤.使用 pimpl 降低編譯依賴
一般庫文件使用者僅需要包含當(dāng)前庫對(duì)應(yīng)的頭文件即可,不應(yīng)該再包含其他的頭文件。假設(shè)庫的頭文件定義如下:
#include "A.h" class demoClass { private: A a; public: void func(); };
此時(shí),若 A 為另外一個(gè)公共庫,則庫的使用者需要在項(xiàng)目中配置 A.h 的路徑;若 A 為自定義類,則庫的提供者還需要額外提供 A.h 文件。
使用 pimpl 方法改進(jìn)則可以減少編譯依賴,僅在類的實(shí)現(xiàn)文件中包含頭文件即可:
// demoClass.h class demoClass { public: void func();//對(duì)外接口 private: class demoClassImpl; demoClassImpl* impl; }; // demoClass.cpp #include "A.h" class demoClass::demoClassImpl { private: A a; public: void func(); };
動(dòng)態(tài)配置功能的實(shí)現(xiàn)方法
①.概述
使用 pimpl 的方式把類的功能實(shí)現(xiàn)用另外一個(gè)獨(dú)立的類來完成,可以在需要的時(shí)候動(dòng)態(tài)的配置類的實(shí)現(xiàn)方法,而保持類的接口不變。
②.代碼示例
公共接口類:
class demoClassImpl; class demoClass { public: void func();//對(duì)外接口 public: demoClassImpl* impl; }; void demoClass::func() { impl->func(); }
功能實(shí)現(xiàn)抽象類:
class demoClassImpl { public: virtual void func() = 0; };
功能實(shí)現(xiàn)派生類:
class demoClassImpl1 : public demoClassImpl { public: void func() { cout << "實(shí)現(xiàn)方式1" << endl; } }; class demoClassImpl2 : public demoClassImpl { public: void func() { cout << "實(shí)現(xiàn)方式2" << endl; } };
功能實(shí)現(xiàn)方式的動(dòng)態(tài)配置:
demoClass* demo = new demoClass;
demoClassImpl1* impl1 = new demoClassImpl1;
demo->impl = impl1;
demo->func();demoClassImpl2* impl2 = new demoClassImpl2;
demo->impl = impl2;
demo->func();
到此這篇關(guān)于C++詳解PIMPL指向?qū)崿F(xiàn)的指針的文章就介紹到這了,更多相關(guān)C++ PIMPL內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)修改函數(shù)代碼HOOK的封裝方法
這篇文章主要介紹了C++實(shí)現(xiàn)修改函數(shù)代碼HOOK的封裝方法,有助于深入了解C++的HOOK原理,需要的朋友可以參考下2014-10-10圖解AVL樹數(shù)據(jù)結(jié)構(gòu)輸入與輸出及實(shí)現(xiàn)示例
這篇文章主要為大家介紹了C++圖解AVL樹數(shù)據(jù)結(jié)構(gòu)輸入與輸出操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05C語言課程設(shè)計(jì)之停車場(chǎng)管理問題
這篇文章主要為大家詳細(xì)介紹了C語言課程設(shè)計(jì)之停車場(chǎng)管理問題,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03C語言中l(wèi)seek()函數(shù)和fseek()函數(shù)的使用詳解
這篇文章主要介紹了C語言中l(wèi)seek()函數(shù)和fseek()函數(shù)的使用詳解,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-08-08Qt QStandardItemModel用法小結(jié)
QStandardItemModel可用作標(biāo)準(zhǔn)Qt數(shù)據(jù)類型的存儲(chǔ)庫,本文主要介紹了Qt QStandardItemModel用法小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-12-12C++17結(jié)構(gòu)化綁定的實(shí)現(xiàn)
這篇文章主要介紹了C++17結(jié)構(gòu)化綁定的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05Qt使用QCamera實(shí)現(xiàn)切換相機(jī),分辨率和圖像捕獲功能
這篇文章主要為大家介紹了如何利用Qt中的相機(jī)類QCamera,取景器類QCameraViewfinder,圖像捕獲類QCameraImageCapture實(shí)現(xiàn)切換相機(jī)、分辨率和圖像捕獲功能,需要的可以了解一下2023-04-04