正在加载http://en.cppreference.com/w/cpp/memory/unique_ptr/reset,
void reset( pointer ptr = pointer() );
template< class U >
void reset( U ) = delete;
void reset( std::nullptr_t p );
1)给定
current_ptr
,由*this
管理的指针执行 以下操作,按此顺序: 保存当前指针old_ptr = current_ptr
的副本; 用参数current_ptr = ptr
覆盖当前指针; 如果旧指针非空,则删除先前管理的对象if(old_ptr != nullptr) get_deleter()(old_ptr)
。2)在动态数组的专业化中,
std::unique_ptr<T[]>
, 提供此模板成员是为了防止将reset()
用于 指向派生的指针(这将导致未定义的行为 阵列)。3)在动态数组的专门化中,
std::unique_ptr<T[]>
, 第三次重载是必要的,以允许重置为nullptr
(这将是 否则被模板超载禁止)。相当于reset(pointer())
现在reset(nullptr)
等同于reset(pointer())
,为什么后者存在?
如果我想重置数组形式unique_ptr,为什么我不能只使用rest(pointer())
?
答案 0 :(得分:7)
在
template< class U >
void reset( U ) = delete;
如果不是,将选择进行nullptr
参数的调用
void reset( std::nullptr_t p );
这就是它存在的原因,允许使用nullptr
进行通话。
示例(使用FIX
编译来定义以抑制编译错误):
#include <cstddef> // std::nullptr_t
struct S
{
void reset( char* ) {}
template< class Type >
void reset( Type ) = delete;
#if FIX
void reset( std::nullptr_t ) {}
#endif
};
auto main() -> int
{
S().reset( nullptr ); // Fails when FIX is not defined.
}
答案 1 :(得分:2)
reset
实现为
pointer old = this->ptr;
this->ptr= newPointer;
delete[] old;
为数组删除模板化重载以防止出现以下情况
class foo{};
class bar : public foo {};
foo* managedPointer = new foo[3];
bar* newPointer = new bar[5];
foo* old = managedPointer;
managedPointer = newPointer;
delete[] old;
这是未定义的行为。第5.3.5节第3段:
[...]在第二种方法(删除数组)中,如果要删除的对象的动态类型与其静态类型不同,则行为是未定义的。
由于已删除的功能仍然参与重载决策,reset(U)
提供的nullptr
与reset(pointer)
的匹配度更高
,允许reset(nullptr)
有一个额外的重载,否则会产生编译器错误,从而导致数组和指针版本之间的接口不一致。