2017-02-21 54 views
-1

我想了解一個來自「api設計爲c + +」書(p。70)的疙瘩示例。「api設計爲c + +」:C++丘疹訪問

// autotimer.h 
class AutoTimer 
{ 
public: 
    explicit AutoTimer(const std::string &name); 
    AutoTimer(); 
    // allow access from other classes/functions in autotimer.cpp 
    class Impl; 
private: 
    Impl* mImpl; 
} 

從文字和例子,我將承擔這就是可以從autotimer.cpp就像在下面的例子中free_f()宣佈免費功能訪問的AutoTimer::Impl成員。

// autotimer.cpp 
class AutoTimer::Impl 
{ 
public: 
    std::string s; 
} 

void free_f(AutoTimer a){ 
    std::cout << a.mImpl->s << std::endl; 
} 

但是,我無法得到這個工作。可悲的是,這本書沒有提供任何進一步的細節。那麼,如何修改free_f()以訪問Impl的私人成員?

是我更加明確,註釋(和第一個例子)

// allow access from other classes/functions in autotimer.cpp

是直接從書「API設計的C++」,我想知道這意味着什麼。

+2

'a'不是指針。 'mImpl'是一個指針。 – juanchopanza

+1

'mImpl'是'AutoTimer'的'private'成員,所以免費函數將無法訪問它。 –

+0

......除非它是「朋友」功能。 –

回答

0

這是未經測試,但應該是合法的C++,如果你的對象是標準的佈局類型:

void free_f(AutoTimer a){ 
    Impl* tmp = *reinterpret_cast<Impl**>(&a); 
    std::cout << tmp->s << std::endl; 
} 

而且因爲你有工作,平普爾你應該通過AutoTimer類型的引用或指針。否則,一個臨時對象將銷燬您的實現對象。

http://en.cppreference.com/w/cpp/language/data_members#Standard_layout

+0

謝謝,這看起來很有趣!這個演員對我來說看起來有點可怕,我還不確定我是否喜歡這個解決方案。你有沒有任何示例/指針表明這是普通的在圖書館處理Pimpl的原因? – user14419

+0

這是我在Windows上處理庫/ DLL的方式。您可以使用朋友函數或專用的'get_pimpl'成員函數來訪問您的實現。兩者都將擴展界面。我不喜歡那樣。我沒有任何其他開源項目的例子。我認爲C++社區對於模板超級魔法非常繁瑣,並且不需要跨越共享庫的邊界。此外,我不在DLL接口中使用'std :: string'或其他運行時類型來防止一些問題(例如並排問題)。 – knivil