何為 pimpl ?

來源:互聯網
上載者:User

標籤:style   blog   color   使用   檔案   資料   ar   問題   

前言

你是否總因標頭檔包含衝突而苦惱?
你是否因標頭檔包含錯亂而苦惱?
你是否因封裝暴露了資料而苦惱?
你是否因經常改動實現而導致重新編譯而苦惱?

在這裡, 這些問題都不是問題, 跟隨作者, 揭秘pimpl.

本文

先來看一段例子:

有A, B 2個類, 分別由A.h, A.cpp, B.h, B.cpp檔案實現.

同時, A類中包含了B類成員, B類中包含了A類成員.

 1 // A.h 2 #include "B.h" 3 class A { 4 private: 5     B b; 6 }; 7  8 // B.h 9 #include "A.h"10 class B {11 private:12     A a;13 };

你是否一眼就看出了問題!

是的, 標頭檔互相包含了, 那怎麼解決此問題?

解決方案?
// A.hclass B;class A {public:    A();    ~A();private:    B *pB;};// A.cpp#include "B.h"A::A(): pB(new B()){}A::~A(){    delete pB;}// B.hclass A;class B {public:    B();    ~B();private:    A *pA;};// B.cpp#include "A.h"B::B(): pA(new A()){}B::~B(){    delete pA;}

我們在標頭檔中互相前置聲明, 這種行為是"不要錢"的, 大夥可以盡情的用.

隨後在源檔案中, 互相包含標頭檔, 在各自的建構函式中new 出對象, 解構函式中 delete 對象.

僅此而已?

接下來才是pimpl的重度解說.

假設我們的A需要實現成員函數 AmemberFunc.

這個成員函數過程複雜, 可能需要分割成多個小函數.

因此就有了一下清單:

func1();

func2();

...

funcN();

過程中還需要一系列成員變數.

因此就有了一下清單:

type1 var1, var2 ... varN;

type2 var1, var2 ... varN;

...

typeN var1, var2 ... varN;

注意, 你需要的僅僅是使用A的AmemberFunc介面.

其他的任何東西在你眼裡都是累贅, 他們並不能讓你更清楚實現, 反而擾亂你的思緒.

 

當你使用一個只有一個介面的對象時, 查看其標頭檔, 發現一堆的成員清單, 

如果你膽子比較大, 或許會去源檔案查看清單中的東西到底都在幹什麼.

這個時候的你已經走向歧途了.

當然, 也可能源檔案已經被編譯成了庫檔案, 你的壯志雄心不得已施展.

再次注意, 你需要的僅僅是這個介面, 至於介面的實現... 除非你的目的是把這個介面一探究竟, 否則純屬浪費時間.

廢話說了不少, 看看解決方案.

// A.hclass A {public:    A();    ~A();    type memberFunc();private:    class impl;    impl *pimpl;};// A.cpp#include "B.h"class A::impl {    type memberFunc()    {        ...    }private:    func1();    func2();    ...    funcN();        type1 var1, var2 ... varN;    type2 var1, var2 ... varN;    ...    typeN var1, var2 ... varN;};A::A(): pimpl(new impl()){}A::~A(){    delete pimpl;}type A::memberFunc(){    return pimpl->memberFunc();}

 A的內部聲明了一個impl類型.

該類執行個體負責實現A的所有功能.

A只需調用impl相應的函數.

此方法隱藏了所有不需要暴露的細節.

並且避免了標頭檔的依賴. (因為實現在源檔案中, 你可以在裡麵包含任意標頭檔不必考慮衝突問題.)

增強了可讀性, 使用者不會被"細節"擾亂思緒.

尾聲

pimpl的功能遠不止這些, 你可以在pimpl中拋出異常, 在外層類中捕獲異常, 從而讓異常完全透明.

還有更多功能, 等著你去發現..

 

當然, pimpl的缺陷也是顯而易見的.

那就是不能內聯! 不過誰會在意呢.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.