В чем разница между новыми и :: новыми
Многие библиотеки, такие как 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 реализован в глобальном масштабе и не может быть переоценен.