开发者

Is it possible to wrap boost sockets with Pimpl?

开发者 https://www.devze.com 2022-12-09 10:20 出处:网络
in a project we want to wrap the Boost Asio socket in a way, that the using class or the wrapping .h does not 开发者_开发百科have to include the boost headers.

in a project we want to wrap the Boost Asio socket in a way, that the using class or the wrapping .h does not 开发者_开发百科have to include the boost headers.

We usually use pointers and forward declarations for wrapped classes.

Foward declaration:

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

And then declaring the socket:

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

(If you don't know scoped_ptr, ignore it, the problem is equal with a standard * pointer.)

But this gives a compiler error:

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

I understand this is because udp is actually not a namespace, but a class itself. We only want to use the inner class though, any ideas?


If you are using pimpl, why are you putting member variables in your header? Are the socket and endpoint typedefs used in your interface? If they are not part of your interface, the whole point of the pimpl idiom is that you don't define the member variables of a class in the header file; they are implementation details.

I expect something like this in the header file:

// ...

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

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

And then in your implementation file:

#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.

To answer your specific question, the types you are trying to use are typedefs in the asio udp class, so the compiler needs to have seen the definition of that class to use it.


With inner types your only option is wrapping everything. Hide scoped pointers themselves inside a forward declared class. Users would see only your API and pass around your own objects instead of boost objects.

In your example though scoped_ptr look like private member declarations, you can get away with simple:

// 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

精彩评论

暂无评论...
验证码 换一张
取 消