В чем разница между новыми и :: новыми

Многие библиотеки, такие как boost, используют ::new и ::delete.

Пример из boost::make_shared

template< class T, class... Args > typename boost::detail::sp_if_not_array< T >::type make_shared( Args && ... args )
{
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );

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

    void * pv = pd->address();

    ::new( pv ) T( boost::detail::sp_forward<Args>( args )... );
    pd->set_initialized();

    T * pt2 = static_cast< T* >( pv );

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

Что это значит? и зачем использовать ::new только что новый?

Ответы

Ответ 1

Класс C может определить свой собственный operator new (это позволяет, например, иметь собственную политику распределения для этого класса и/или предоставлять для него некоторый Allocator. Многие стандартные шаблоны контейнеров принимают необязательный аргумент распределителя, например второй аргумент для std::vector, см. также std::allocator и этот пример).

Если вы закодируете new C, этот оператор будет использоваться (если он существует).

Если вы code ::new C, используется глобальное new

В вашем примере используется глобальное размещение new

Ответ 2

new, new[], delete и delete[] (включая варианты размещения) являются переопределяемыми как в class и в глобальном масштабе, хотя последнее не рекомендуется.

Когда вы видите ::new, вы используете глобальный new оператор.

Ответ 3

В общем случае, когда оператор разрешающей способности (:: :) используется без каких-либо спецификаторов в LHS, он ссылается на глобальную область. Вот и это одно и то же.

Приступая к new оператору, он может быть перегружен в локальном и внешнем масштабе. Следовательно, для доступа к глобальному варианту разрешения разрешений используется оператор.

Ответ 4

new могут быть переопределены и заменены. Таким образом, простое указание new не всегда получит new вы хотите.

В этом конкретном случае мы рассматриваем новое размещение:

void * pv = pd->address();

::new( pv ) T( boost::detail::sp_forward<Args>( args )... );

это то, где мы пытаемся построить T в местоположении pv.

Для того, чтобы избежать возможности того, что overrids из new вызываются вместо "реальной" размещения new, вы должны использовать ::new( void pointer here ) type( arguments... ); , Это new может быть заменено и не отменено.

Ответ 5

Нормальный новый оператор реализуется в шкале классов и может быть переопределен, а :: new реализован в глобальном масштабе и не может быть переоценен.