Domanda

in un progetto vogliamo avvolgere il socket Boost Asio in un modo, in modo che la classe utilizzante o il wrapping .h non debba includere le intestazioni boost.

Usiamo solitamente puntatori e dichiarazioni forward per le classi wrapped.

Dichiarazione futura:

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

E quindi dichiarando il socket:

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

(Se non conosci scoped_ptr, ignoralo, il problema è uguale a un puntatore * standard.)

Ma questo dà un errore del compilatore:

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

Lo capisco perché udp non è in realtà uno spazio dei nomi, ma una classe stessa. Vogliamo solo usare la classe interiore, qualche idea?

È stato utile?

Soluzione

Con i tipi interni l'unica opzione è racchiudere tutto. Nasconde gli stessi puntatori con ambito all'interno di una classe dichiarata diretta. Gli utenti vedrebbero solo la tua API e passerebbero in giro i tuoi oggetti invece di oggetti boost.

Nel tuo esempio sebbene scoped_ptr assomigli a dichiarazioni di membri privati, puoi cavartela con semplici:

// 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)
{ 
}

Altri suggerimenti

Se si utilizza pimpl, perché si inseriscono le variabili membro nell'intestazione? I typedef di socket ed endpoint sono utilizzati nella tua interfaccia? Se non fanno parte della tua interfaccia, l'intero punto del linguaggio del pimpl è che non definisci le variabili membro di una classe nel file header; sono dettagli di implementazione.

Mi aspetto qualcosa di simile nel file di intestazione:

// ...

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

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

E poi nel tuo file di implementazione:

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

Per rispondere alla tua domanda specifica, i tipi che stai cercando di usare sono typedef nella classe asio udp, quindi il compilatore deve aver visto la definizione di quella classe per usarla.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top