为什么unique_ptr有两个函数reset和operator=做类似的事情,但不重载?



我知道这听起来像是一个奇怪的问题,但我很好奇。Unique_ptr operator=将r值引用作为参数并调用reset(r.r release()),然后移动自定义delete。最后,操作符返回*this。如:

// this is pseudo code
unique_ptr& operator=(unique_ptr&& r)
{
reset(r.release());  // Change managed pointer
setDeleter(r.getDeleter());
return *this;
}

unique_ptr reset函数以左值原始指针作为参数,在改变其管理的指针后删除旧指针。在这两者之间,它们具有改变被管理指针的相同行为。该行为由相同的reset()函数处理。这两个函数做类似的事情,除了参数的不同之外,我想不出一个单独的用例,所以我想知道是否有可能重载它们。如:

// this is pseudo code
unique_ptr& operator=(unique_ptr&& r) // or a function named reset
{
changeManagedPtr(r.release()); // and delete old pointer
setDeleter(r.getDeleter());
return *this;
}
unique_ptr& operator=(pointer p) // or a function named reset
{
changeManagedPtr(p); // and delete old pointer
// setDeleter(r.getDeleter()); there is no deleter in p
return *this;
}

为什么这两个函数是分开编写的,而不是作为同名的重载函数?如果可能的话,是不是可以使用一些不那么令人困惑的东西呢?

unique_ptr<int> uniqPtrInt, dest;
int* rawPtrInt = new int;
dest = rawPtrInt;
// some work..
dest = uniqPtrInt;

我假设错了吗?有没有什么我不知道的稳定性问题?

unique_ptr& unique_ptr::operator=(pointer p)可以实现,但委员会选择不这样做,原因与他们明确unique_ptr::unique_ptr(pointer p)的原因相同。

唯一指针表示对象的唯一所有权。如果您可以隐式地从原始指针构造或分配它们,则很容易意外地转移所有权(并且在没有意识到的情况下,执行未定义行为,如双删除)。

std::unique_ptr的赋值语义是move-only,即move赋值。再加上一个不透明的看起来像pointer的复制分配,它在引子下面移动,可能会有导致混乱的风险,而std::unique_ptr的设计考虑了安全性("使其难以被滥用")。这就拒绝了用pointer重载赋值操作符的想法。

转到reset():虽然reset()也可以提供重载来用std::unique_ptr的重载来代替*this的托管对象,但这意味着在std::unique_ptr的API中添加另一种执行move-assignment的方式,这种操作应该更倾向于move-assignment op(语义上)。

最新更新