É possível embrulhar soquetes impulso com Pimpl?
-
06-07-2019 - |
Pergunta
em um projeto que queremos envolvê tomada Asio o impulso de uma forma, que o uso de classe ou na embalagem .h não tem de incluir os cabeçalhos impulso.
Normalmente, usamos ponteiros e declarações para a frente para as classes envolvidas.
declaração Foward:
namespace boost
{
namespace asio
{
namespace ip
{
class udp;
}
}
}
E, em seguida, declarar o soquete:
scoped_ptr<boost::asio::ip::udp::socket> socket_;
scoped_ptr<boost::asio::ip::udp::endpoint> receiveEp_;
(Se você não sabe scoped_ptr, ignorá-lo, o problema é igual com um ponteiro padrão *).
Mas isso dá um erro do compilador:
error C2027: use of undefined type 'boost::asio::ip::udp'
Eu entendo isso é porque udp não é realmente um espaço de nomes, mas uma classe em si. Nós só quer usar a classe interna, porém, todas as idéias?
Solução
Com tipos internos sua única opção é embrulhar tudo. Esconder escopo ponteiros-se dentro de uma classe para a frente declarado. Os usuários só vêem a sua API e passar em torno de seus próprios objetos em vez de objetos impulso.
No seu exemplo, embora scoped_ptr olhar como declarações de membro privadas, você pode sair com simples:
// 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)
{
}
Outras dicas
Se você estiver usando pimpl, por que você está colocando variáveis ??de membro em seu cabeçalho? Está tomada e ponto final typedefs usado em sua interface? Se eles não fazem parte de sua interface, toda a questão do idioma pimpl é que você não definir as variáveis ??de membro de uma classe no arquivo de cabeçalho; eles são detalhes de implementação.
Eu espero que algo como isto no arquivo de cabeçalho:
// ...
class MyClass {
public:
MyClass();
// .. Other member functions
private:
struct Imp;
boost::shared_ptr<Imp> m_imp; // This is the only member variable.
};
E, em seguida, em seu arquivo de implementação:
#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.
Para responder à sua pergunta específica, os tipos que você está tentando usar são typedefs na classe asio udp, assim as necessidades do compilador ter visto a definição dessa classe para usá-lo.