很多图书馆都喜欢使用::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
而不是新的?
答案 0 :(得分:42)
类C
可以定义自己的operator new
(例如,这可以为该类设置自己的分配策略,和/或为其提供一些Allocator。许多标准containers模板接受可选的allocator参数,例如std::vector
的第二个参数;另请参阅std::allocator
和this示例。)
如果编码new C
,将使用该运算符(如果存在)。
如果您对::new C
进行编码,则使用全局new
您的示例是使用全局placement new
答案 1 :(得分:21)
new
,new[]
,delete
和delete[]
(包括展示位置变体)可覆盖两者 class
< em>和在全球范围内,尽管做后者是不明智的。
当您看到::new
时,您正在使用全局new
运算符。
答案 2 :(得分:6)
通常,只要在LHS使用范围分辨率(::
)运算符而没有任何说明符,它就会引用全局范围。这也是一样的。
来到运营商new
,它可以在本地和外部范围重载。因此,为了访问全局变体,使用范围解析运算符。
答案 3 :(得分:2)
new
可以覆盖并替换。因此,简单地说明new
并不总能获得您想要的new
。
在这个特定情况下,我们正在考虑新的位置:
void * pv = pd->address();
::new( pv ) T( boost::detail::sp_forward<Args>( args )... );
这是我们尝试在T
位置构建pv
的位置。
为避免调用new
的覆盖而不是“真实”展示位置new
,您必须使用::new( void pointer here ) type( arguments... );
。该特定new
既不能被替换也不能被覆盖。
答案 4 :(得分:-1)
普通的new运算符是在类级别实现的,可以覆盖,而:: new是在全局范围内实现的,不能覆盖。