Где boost :: make_shared размер выделения памяти для базового объекта и объекта подсчета ссылок?

Я пытаюсь понять как boost::make_shared выполняет выделение памяти для объекта, управляемого boost::shared_ptr и объект подсчета ссылок ( shared_ptr использует) вместе.

make_shared Функция начинает выполнение здесь:

template< class T, class A1, class A2, class A3 >
typename boost::detail::sp_if_not_array< T >::type make_shared( A1 && a1, A2 && a2, A3 && a3 )
{
//Seems to create the smart_ptr for the object
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );

//Not sure?
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );

//Calculates the address at which the bulk-allocation begins
void * pv = pd->address();

//Allocates the memory at address pv?
::new( pv ) T(
boost::detail::sp_forward<A1>( a1 ),
boost::detail::sp_forward<A2>( a2 ),
boost::detail::sp_forward<A3>( a3 )
);

//Not sure
pd->set_initialized();

//Not sure
T * pt2 = static_cast< T* >( pv );

//Not sure
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}

Может ли кто-нибудь помочь объяснить оставшиеся строки?

Я пытаюсь определить, где размер выделения памяти (объект, на который указывает а также определяется объект подсчета ссылок shared_ptr)?

Меня бросает то, что address() кажется, не учитывает размер T объект при выделении адреса для размещения на.

(Я действительно не понимаю, что три AX параметры, которые вводят метод и передаются на размещение new() вызов)

0

Решение

Давайте рассмотрим это построчно

  boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );

Это создает общий указатель, но ключ здесь — удалитель. BOOST_SP_MSD(T) это макрос, который разрешает удаление, с достаточным пространством для ваших данных. Таким образом, блок подсчета ссылок общего указателя также включает пространство для удалителя, которое теперь включает пространство для вашего T

    //Not sure?
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );

Это получает адрес удаления из общего указателя. Это будет указывать на созданный выше удалитель.

    //Calculates the address at which the bulk-allocation begins
void * pv = pd->address();

Это возвращает начальный адрес для типа T, который в настоящее время неинициализирован и является частью средства удаления

    //Allocates the memory at address pv?
::new( pv ) T(
boost::detail::sp_forward<A1>( a1 ),
boost::detail::sp_forward<A2>( a2 ),
boost::detail::sp_forward<A3>( a3 )
);

Это новое место размещения. Это создает ваш T по адресу, указанному в pv, Он передает 3 аргумента, потому что это 3-аргументная версия make_shared,

    //Not sure
pd->set_initialized();

Это внутренний флаг в удалителе, который позволяет ему знать, что T был построен (так что, когда удалитель operator() называется, это его уничтожит)

    //Not sure
T * pt2 = static_cast< T* >( pv );

Это бросает пустоту * выше в T*, Честно говоря, я не уверен, почему они просто не сохранили результат размещения новых.

    //Not sure
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );

Это необходимо для обеспечения enable_shared_from_this функциональность. Эта внутренняя функция устанавливает базовый механизм для enable_shared_from_this, Обычно он вызывается, когда вы помещаете что-то в shared_ptr

    return boost::shared_ptr< T >( pt, pt2 );

Это на самом деле создает новый boost::shared_ptr который использует ту же область подсчета ссылок, что и pt, но это get() и связанные методы вернутся pt2, который является указателем на T, который хранится в удалителе.

4

Другие решения


По вопросам рекламы [email protected]