2009-10-28 108 views
0

在一個項目中,我們想要以某種方式包裝Boost Asio套接字,使用類或包裝.h不必包含boost頭文件。是否可以用Pimpl封裝boost套接字?

我們通常使用包裝類的指針和轉發聲明。

FOWARD聲明:

namespace boost 
{ 
    namespace asio 
    { 
    namespace ip 
    { 
     class udp; 
    } 
    } 
} 

然後宣佈插座:

scoped_ptr<boost::asio::ip::udp::socket> socket_; 
    scoped_ptr<boost::asio::ip::udp::endpoint> receiveEp_; 

(如果你不知道scoped_ptr的,忽略它,這個問題是一個標準的*指針相等)。

但是,這給出了一個編譯器錯誤:

error C2027: use of undefined type 'boost::asio::ip::udp' 

我明白這是因爲udp實際上不是一個命名空間,而是一個類本身。我們只想使用內部類,任何想法?

回答

2

對於內部類型你唯一的選擇是包裝一切。將範圍指針本身隱藏在一個前向聲明的類中。用戶只會看到你的API並傳遞你自己的對象而不是提升對象。

在你的榜樣,雖然scoped_ptr的樣子私有成員聲明,​​你可以逃脫簡單:

// header 
class SomeClass 
{ 
public: 
    SomeClass(); 
    // stuff 
private: 
    scoped_ptr<class pimpl_bla> _m; 
}; 

// source 
class pimpl_bla 
{ 
public: 
    scoped_ptr<boost::asio::ip::udp::socket> socket_; 
}; 

SomeClass::SomeClass() 
    :_m(new pimpl_bla) 
{ 
} 
+0

也就是說,我將不得不定義所有的公共職能兩次..和SomeClass的將簡單地把它們傳遞給pimpl_bla ? – Tarnschaf 2009-10-28 03:47:43

+0

取決於什麼是有道理的。我通常使用pimpl類作爲數據成員存儲桶(也通常是一個結構體),它們可以通過與宿主類完全相同的方式訪問,就像它們是它自己的一樣。但我很懶。 :) – Eugene 2009-10-28 04:32:02

+0

下面談談完全相同的事情順便說一句。 – Eugene 2009-10-28 04:33:32

3

如果您使用的是pimpl,爲什麼要將成員變量放在標題中?您的界面中使用了套接字和端點類型定義?如果它們不是你的接口的一部分,pimpl習語的全部意義在於你沒有在頭文件中定義一個類的成員變量;他們是實施細節。

我希望在頭文件是這樣的:

// ... 

class MyClass { 
public: 
    MyClass(); 
    // .. Other member functions 

private: 
    struct Imp; 
    boost::shared_ptr<Imp> m_imp; // This is the only member variable. 
}; 

,然後在實現文件:

#include <boost/asio/whatever.hpp> 

struct MyClass::Imp 
{ 
    scoped_ptr<boost::asio::ip::udp::socket> socket_; 
    scoped_ptr<boost::asio::ip::udp::endpoint> receiveEp_; 

    // Remainder of implementation class ... 
}; 

// Other implementation details. 

爲了回答您的具體問題,你要使用的類型的typedef在asio udp類中,編譯器需要看到該類的定義才能使用它。

相關問題