2009-10-25 73 views
10

Pimpl's是許多C++代碼中樣板的來源。它們看起來像是宏,模板和一些外部工具幫助可以解決的組合,但我不確定最簡單的方法是什麼。 I've seen templates有助於做一些提升但不是太多 - 你最終還是需要爲你想要包裝的每個類的方法編寫轉發函數。有更容易的方法嗎?自動化C++類的pimpl'ing - 有沒有簡單的方法?

我在想象一個工具作爲make過程的一部分。你希望你的公共頭文件是pimpl的類,所以你提供了一些輸入文件,比如說pimpl.in,它列出了你想要打包的類(實現un-pimpl'd),然後檢查這個文件,生成pimpl類,並且在'make install'期間只安裝它們的頭文件(不是原始類的頭文件)。問題是如果沒有完整的C++解析器,我沒有辦法做到這一點,即使編譯器供應商也無法正確使用。也許這些類可以用一些方式編寫,這使得外部工具的工作更容易,但是我確信我最終會錯過各種各樣的角落案例(例如,模板化類和/或模板化成員函數)。

任何想法?其他人是否已經爲此問題提供瞭解決方案?

+0

懶C++做類似的事情 – Amnon 2010-12-23 13:44:17

回答

6

不,不是一個簡單的答案。 :-(我認爲幾乎所有的OO專家都說「偏好構圖而不是繼承」,所以會有語言支持讓構圖變得比繼承更容易。

0

一種選擇是使用一個接口類,而不是:

class ClassA { 
    virtual void foo() = 0; 
    static ClassA *create(); 
}; 

// in ClassA.cpp 

class ImplA : public ClassA { 
/* ... */ 
}; 
ClassA *ClassA::create() { 
    return new ImplA(); 
} 

但這不過從獲取虛函數表函數指針增加開銷。

除此之外,我想不出任何這樣的工具。正如你所說的,解析C++並不重要,並且還有其他語言,在這些語言中,問題較少(例如,C#或Java遲遲綁定所有內容,因此您可以在以後更改其內存中佈局而不會出現問題)。

+4

C#最堅決不「晚綁定一切」 – 2009-10-25 18:56:03

2

我不是說這是好事記)
但是你可以用重載操作實驗 - >

#include <memory> 
#include <iostream> 

class X 
{ 
    public: 
    void plop() 
    { 
     std::cout << "Plop\n"; 
    } 
}; 

class PimplX 
{ 
    public: 
     PimplX() 
     { 
      pimpl.reset(new X); 
     } 
     X* operator->() 
     { 
      return pimpl.get(); 
     } 
    private: 
     PimplX(PimplX const&); 
     PimplX& operator=(PimplX const&); 
     std::auto_ptr<X> pimpl; 
}; 


int main() 
{  
    PimplX  x; 

    x->plop(); 
} 
+0

這是一個有趣的想法,但你會的。最終仍然直接調用X對象上的函數,這意味着您需要公開X的頭和定義,所以X不會是完全不透明。另一方面,如果你主要是爲了ABI,而不是讓類不透明(並且可以相信用戶不會直接選擇直接使用X,而是當它的頭部可用時),我認爲它會好的。 – 2010-05-15 23:09:12

+0

此外,在C++中的類定義內定義的函數隱式內聯。您需要將PimplX的構造函數和操作符 - >定義從類中移出,以免將調用方綁定到X的ABI。 – 2010-05-15 23:10:23

相關問題