Toby
Toby

Reputation: 3905

Initialize Boost shared_ptr in constructor

I have a class, which has aboost::asio::io_service object. I want this object stored in a boost::shared_ptr.

So my header looks like this ( I got rid of any unnecessary code so it doesn't distract )

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

When I now create an object of CommandDispatcherI want that an io_service object to be initialized for the pointer. Now I'm not quite sure how to do this. I looked up two differentsolutions but only one is working and I'm not quite sure if it's a nice one. But see for yourself:

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
}

So the reset call is working, but I think this one is actually to reassign the pointer. So it is not wrong to use it but it doesn't seem like the nicest solution to me. The suggestion for the make_shared call I found in another question. But this one just won't work for me ( I implemented it as described in the official boost example ). I get

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

I'm not quite sure how to do this now, which would be the best way ( maybe there is a complete other option to do it ). Or maybe I'm doin it right, but I'm gettin something with the io_servicewrong.

Hope this question hasn't been already here in this way ( I looked up some old question, but no answer seemed to fit for me ).

Upvotes: 7

Views: 11750

Answers (4)

Mike Seymour
Mike Seymour

Reputation: 254721

If you're using make_shared, then you don't use new yourself; you pass it the constructor arguments, and it will create the object for you. In this case, there are not arguments, so just do:

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

although it would be nicer to initialise it in the initialiser list rather than the constructor body:

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

Using make_shared has the advantage that it will only perform a single memory allocation, while initialisation using new boost::asio::io_service will require two (one for the object, and one for the shared reference count).

Upvotes: 8

BЈовић
BЈовић

Reputation: 64283

There are several ways :

  • for simple initialization, create in the constructor's list :

.

CommandDispatcher::CommandDispatcher() :
  m_ioservice( new boost::asio::io_service )
{
}
  • for dependency injection using a factory :

.

CommandDispatcher::CommandDispatcher() :
  m_ioservice( Factory::Create() )
{
}
  • for dependency injection using by passing already created object :

.

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

Upvotes: 0

Useless
Useless

Reputation: 67812

The nice way is probably

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

because the alternative has you default-constructing the shared_ptr first, and then reassigning it.

Or, equivalently using make_shared:

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

Upvotes: 1

ronag
ronag

Reputation: 51283

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
}

Upvotes: 7

Related Questions