是否可以用 Pimpl 封装 boost 插座?

发布于 2024-08-10 00:20:34 字数 592 浏览 9 评论 0原文

在项目中,我们希望以某种方式包装 Boost Asio 套接字,使使用类或包装 .h 不必包含 boost 标头。

我们通常对包装类使用指针和前向声明。

前向声明:

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 实际上不是命名空间,而是一个类本身。我们只想使用内部类,有什么想法吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雨巷深深 2024-08-17 00:20:34

如果您使用 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.

为了回答您的具体问题,您尝试使用的类型是 asio udp 类中的 typedef,因此编译器需要看到该类的定义使用它。

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.

眼睛会笑 2024-08-17 00:20:34

对于内部类型,您唯一的选择就是包装所有内容。将作用域指针本身隐藏在前向声明的类中。用户只会看到您的 API 并传递您自己的对象而不是 boost 对象。

在您的示例中,虽然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)
{ 
}

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)
{ 
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文