Initialize Boost shared_ptr in constructor

11,565

Solution 1

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
}

Solution 2

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

Solution 3

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>())
{
}
Share:
11,565
Toby
Author by

Toby

Updated on July 23, 2022

Comments

  • Toby
    Toby almost 2 years

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

  • Toby
    Toby about 12 years
    Yeah this works ( and seems nice ) but what I'm not understanding is where the difference between this call is and m_ioservice = new boost::asio::io_service which actually doesn't work???
  • Toby
    Toby about 12 years
    Haha sorry for formulating it a bit vague. If u say CommandDispatcher::CommandDispatcher() : m_ioservice(new boost::asio::io_service) isn't that the same as sayin CommandDispatcher::CommandDispatcher() { m_ioservice = new boost::asio::io_service; } ?
  • ronag
    ronag about 12 years
  • Mike Seymour
    Mike Seymour about 12 years
    @Toby: m_ioservice(new io_service) is using the explicit shared_ptr constructor that takes a raw pointer. m_ioservice = new io_service won't work because there's neither an assignment operator nor a non-explicit constructor taking a raw pointer; you have to either use reset, or explicitly create a shared_ptr to assign.
  • meakgoz
    meakgoz over 8 years
    +1 for different versions, and indication of correct way to do it as a suggestion. You may need ver 2 in that case: Lets assume you need class A to instantiate class B & you have to do something before you instantiate class A. By the way, I also tried ver 3, it says boost does not have make_shared func, should I include something?