Pimplでブーストソケットをラップすることは可能ですか?
-
06-07-2019 - |
質問
プロジェクトでは、使用クラスまたはラッピング.hにブーストヘッダーを含める必要がないように、Boost Asioソケットをラップします。
通常、ラップされたクラスにはポインターと前方宣言を使用します。
前向きな宣言:
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が実際には名前空間ではなく、クラス自体であるためです。ただし、内部クラスのみを使用したいのですが、アイデアはありますか?
解決
内部タイプでは、すべてをラップすることが唯一のオプションです。前方宣言されたクラス内でスコープポインター自体を非表示にします。ユーザーには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)
{
}
他のヒント
pimplを使用している場合、なぜヘッダーにメンバー変数を入れているのですか?インターフェースでソケットとエンドポイントのtypedefが使用されていますか?インターフェイスの一部ではない場合、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.
特定の質問に答えるために、使用しようとしている型はasio udpクラスのtypedefであるため、コンパイラはそれを使用するためにそのクラスの定義を見ている必要があります。
所属していません StackOverflow