Инициализируйте Boost shared_ptr в конструкторе - PullRequest
7 голосов
/ 06 февраля 2012

У меня есть класс, у которого есть boost::asio::io_service объект.Я хочу, чтобы этот объект хранился в boost::shared_ptr.

Так что мой заголовок выглядит следующим образом (я избавился от ненужного кода, чтобы он не отвлекал)

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

Когда я сейчассоздать объект CommandDispatcher Я хочу, чтобы объект io_service был инициализирован для указателя.Теперь я не совсем уверен, как это сделать.Я посмотрел два разных решения, но работает только одно, и я не совсем уверен, хорошее ли оно.Но убедитесь сами:

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
}

Итак, вызов reset работает, но я думаю, что на самом деле этот вызов на самом деле переназначает указатель.Так что это не неправильно использовать его, но это не кажется мне лучшим решением.Предложение для звонка make_shared я нашел в другом вопросе.Но этот просто не будет работать для меня (я реализовал это, как описано в официальном примере надстройки).Я получаю

/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_service неправильно.

Надеюсь, что этот вопрос еще не был здесь таким образом (я посмотрел старый вопрос, но нетмне показалось, что ответ подходит).

Ответы [ 4 ]

8 голосов
/ 06 февраля 2012

Если вы используете make_shared, то вы не используете new самостоятельно; Вы передаете ему аргументы конструктора, и он создаст объект для вас. В этом случае аргументов нет, просто сделайте:

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

хотя было бы лучше инициализировать его в списке инициализаторов, а не в теле конструктора:

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

Использование make_shared имеет то преимущество, что оно будет выполнять только одно выделение памяти, в то время как для инициализации с использованием new boost::asio::io_service потребуется два (один для объекта и один для общего счетчика ссылок).

7 голосов
/ 06 февраля 2012
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
}
1 голос
/ 06 февраля 2012

Путь nice , вероятно,

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

, потому что в альтернативе вы сначала создаете shared_ptr по умолчанию, а затем переназначаете его.

Илиэквивалентно используя make_shared:

CommandDispatcher::CommandDispatcher() : 
  m_ioservice(boost::make_shared<boost::asio::io_service>())
{
}
0 голосов
/ 06 февраля 2012

Есть несколько способов:

  • для простой инициализации создайте в списке конструктора:

.

CommandDispatcher::CommandDispatcher() :
  m_ioservice( new boost::asio::io_service )
{
}
  • для внедрения зависимости с использованием фабрики:

.

CommandDispatcher::CommandDispatcher() :
  m_ioservice( Factory::Create() )
{
}
  • для внедрения зависимости с помощью передачи уже созданного объекта:

.

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