2012-02-06 17 views
6

Ho una classe, che ha un oggetto boost::asio::io_service. Voglio questo oggetto memorizzato in un boost::shared_ptr.Inizializza Boost shared_ptr nel costruttore

Quindi il mio colpo di testa si presenta così (mi sono liberato di qualsiasi codice non necessario in modo da non distrarre)

class CommandDispatcher 
{ 
private: 
    boost::shared_ptr<boost::asio::io_service> m_ioservice; 
public: 
    CommandDispatcher(); 
}; 

Quando ora creo un oggetto di CommandDispatcher voglio che un oggetto io_service da inizializzare per il puntatore. Ora non sono abbastanza sicuro di come farlo. Ho consultato due diverse soluzioni, ma solo una funziona e non sono sicuro se sia una buona idea. Ma vedere di persona:

CommandDispatcher::CommandDispatcher() 
{ 
    m_ioservice.reset(new boost::asio::io_service);   // this actually works 
    //m_ioservice = boost::make_shared<boost::asio::io_service> 
    // (new boost::asio::io_service);      // this doesn't work 
} 

Quindi la chiamata reset sta lavorando, ma credo che questo è in realtà per riassegnare il puntatore. Quindi è non sbagliato usarlo ma non mi sembra la soluzione migliore per me. Il suggerimento per la chiamata make_shared l'ho trovato in un'altra domanda. Ma questo non funzionerà per me (l'ho implementato come descritto nell'esempio ufficiale di boost). Ottengo

/usr/local/include/boost/smart_ptr/make_shared.hpp:189: error: invalid conversion from ‘boost::asio::io_service*’ to ‘size_t’

/usr/local/include/boost/smart_ptr/make_shared.hpp:189: error: initializing argument 1 of ‘boost::asio::io_service::io_service(size_t)’

io non sono molto sicuro come fare questo oggi, che sarebbe il modo migliore (forse c'è una completa altra opzione per farlo). O forse sto facendo bene, ma sto ottenendo qualcosa con il io_service sbagliato.

Spero che questa domanda non sia già stata qui in questo modo (ho cercato una vecchia domanda, ma nessuna risposta sembrava adattarsi a me).

+0

Perché le variabili private sono elencate prima dei metodi pubblici? Sicuramente l'interfaccia pubblica è più importante dei dettagli di implementazione privata? :)

+0

Beh, in realtà ho pensato (e imparato qualche tempo fa) che è "buon tono" per dichiarare in primo luogo le variabili dei membri pubblici e privati ​​e quindi dichiarare metodi pubblici e privati. – Toby

+0

Penso che la maggior parte delle persone sarebbe più interessata all'interfaccia pubblica, al contrario di quali variabili si utilizzano per realizzarla. –

risposta

7
CommandDispatcher::CommandDispatcher() 
    : m_ioservice(new boost::asio::io_service) // ver 1. this is how you should do it. 
{ 
    //m_ioservice.reset(new boost::asio::io_service); // ver 2  
    //m_ioservice = boost::make_shared<boost::asio::io_service>(); // ver 3 
} 
+0

Sì, questo funziona (e sembra bello) ma quello che non sto capendo è dove la differenza tra questa chiamata e 'm_ioservice = nuovo boost :: asio :: io_service' che in realtà non funziona ??? – Toby

+0

Quale chiamata è "questa chiamata"? – ronag

+0

Haha scusa per averlo formulato un po 'vago. Se dici 'CommandDispatcher :: CommandDispatcher(): m_ioservice (nuovo boost :: asio :: io_service)' non è lo stesso di sayin 'CommandDispatcher :: CommandDispatcher() {m_ioservice = new boost :: asio :: io_service; } '? – Toby

8

Se si utilizza make_shared, non si utilizza new da soli; gli passi gli argomenti del costruttore e creerà l'oggetto per te. In questo caso, non ci sono argomenti, quindi basta fare:

m_ioservice = boost::make_shared<boost::asio::io_service>(); 

anche se sarebbe bello per inizializzare nell'elenco initialiser piuttosto che il corpo del costruttore:

CommandDispatcher::CommandDispatcher() : 
    m_ioservice(boost::make_shared<boost::asio::io_service>()) 
{ 
} 

Utilizzando make_shared ha il vantaggio che eseguirà solo una singola allocazione di memoria, mentre l'inizializzazione utilizzando new boost::asio::io_service richiederà due (uno per l'oggetto e uno per il conteggio dei riferimenti condivisi).

1

Il bella modo è probabilmente

CommandDispatcher::CommandDispatcher() : 
    m_ioservice(new boost::asio::io_service) 
{ 
} 

perché l'alternativa è di default-costruzione del shared_ptr prima, e poi riassegnandolo.

o, equivalentemente utilizzando make_shared:

CommandDispatcher::CommandDispatcher() : 
    m_ioservice(boost::make_shared<boost::asio::io_service>()) 
{ 
} 
0

Ci sono diversi modi:

  • per semplice inizializzazione, creare nella lista del costruttore:

.

CommandDispatcher::CommandDispatcher() : 
    m_ioservice(new boost::asio::io_service) 
{ 
} 
  • per l'iniezione di dipendenza con una fabbrica:

.

CommandDispatcher::CommandDispatcher() : 
    m_ioservice(Factory::Create()) 
{ 
} 
  • iniettabile dipendenza utilizzando passando oggetto già creato:

.

CommandDispatcher::CommandDispatcher(boost::shared_ptr<boost::asio::io_service> service) : 
    m_ioservice(service) 
{ 
} 
Problemi correlati