我知道这听起来可能是一个奇怪的问题,但我很好奇。unique_ptr operator=将一个r值引用作为参数,并调用reset(r.release()),然后移动自定义删除器。最后,operator返回 *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;
我是不是假设错了?有没有我不知道的稳定性后果?
2条答案
按热度按时间omqzjyyz1#
unique_ptr& unique_ptr::operator=(pointer p)
可以实现,但委员会选择不实现,原因与他们明确unique_ptr::unique_ptr(pointer p)
的原因相同。unique指针表示对象的唯一所有权。如果你可以从原始指针隐式地构造或赋值它们,那么很容易意外地转移所有权(并且,在没有意识到你已经转移了所有权的情况下,做一些未定义的行为,比如双重删除)。
arknldoa2#
std::unique_ptr
的赋值语义是move-only,即移动赋值。在此基础上添加一个从pointer
看起来不透明的复制赋值,它在引擎盖下移动,可能会导致混乱,而std::unique_ptr
的设计考虑到了安全性(“使其难以误用”)。这拒绝了用pointer
重载来重载赋值运算符的想法。超过
reset()
:虽然reset()
也可论证地提供重载以用std::unique_ptr
重载的受管对象替换*this
的受管对象,但这将意味着向std::unique_ptr
的API添加本质上执行移动指派的另一方式,移动指派是其中移动指派操作应得到支持(语义上)的操作。