简体   繁体   English

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

[英]Why do unique_ptr have two functions reset and operator= that do similar things but not overload?

I know this may sound like a strange question, but I'm very curious.我知道这听起来像是一个奇怪的问题,但我很好奇。 unique_ptr operator= takes an r-value reference as a parameter and calls reset(r.release()), then move custom deleter. unique_ptr operator= 将右值引用作为参数并调用 reset(r.release()),然后移动自定义删除器。 finally, operator returns *this.最后,运算符返回 *this。 like:喜欢:

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

unique_ptr reset function takes l-value raw pointer as a parameter and delete the old pointer after changing the pointer it manages. unique_ptr reset function 以左值原始指针为参数,在改变它管理的指针后删除旧指针。 Between the two, they have the same behavior of changing the pointer being managed.在两者之间,它们具有相同的改变被管理指针的行为。 And that behavior is handled by the same reset() function. These two functions do similar things, and I couldn't think of a separate use case other than the difference in parameters, so I wondered if it might be possible to overload them.并且该行为由相同的 reset() function 处理。这两个函数做类似的事情,除了参数不同之外我想不出一个单独的用例,所以我想知道是否可以重载它们。 like:喜欢:

// 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;
}

Why are the two functions written separately and not as overloaded functions with the same name?为什么这两个函数是分开写的,而不是同名的重载函数呢? If it were possible, wouldn't it be possible to use something less confusing like this:如果可能的话,难道不能使用像这样不那么令人困惑的东西吗:

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

Am I assuming something wrong?我假设有什么问题吗? Are there any stability ramifications that I'm not aware of?是否有任何我不知道的稳定性影响?

unique_ptr& unique_ptr::operator=(pointer p) can be implemented, but the committee chose not to, for the same reason that they made unique_ptr::unique_ptr(pointer p) explicit. unique_ptr& unique_ptr::operator=(pointer p)可以实现,但委员会选择不这样做,原因与他们明确unique_ptr::unique_ptr(pointer p)的原因相同。

A unique pointer represents unique ownership of an object. If you could implicitly construct or assign them from raw pointers, it would be very easy to accidentally transfer ownership (and, not realising that you have, do something with undefined behaviour, like double delete).唯一指针代表 object 的唯一所有权。如果您可以从原始指针隐式构造或分配它们,则很容易意外转移所有权(并且,没有意识到您已经做了一些未定义的行为,例如双重删除) .

The assignment semantics of std::unique_ptr is move-only, ie move assignment. std::unique_ptr的赋值语义是 move-only,即移动赋值。 Adding onto that an opaque copy-assignment-looking from pointer which moves under the hood would arguably risk leading to confusion, and std::unique_ptr was designed with safety in mind ("make it hard to misuse").再加上一个不透明的复制赋值,从在引擎盖下移动的pointer来看,可以说有导致混淆的风险,而std::unique_ptr的设计考虑到了安全性(“使其难以滥用”)。 That rejects the idea of overloading the assignment operator with a pointer overload.这拒绝了用pointer重载重载赋值运算符的想法。

Over to reset() : whilst reset() could arguably also provide an overload to replace the managed object of *this with that of a std::unique_ptr overload, it would mean adding to the API of std::unique_ptr another way of essentially performing move-assignment, an operation where move-assignment op should be favored (semantically).转到reset() :虽然reset()可以说也可以提供一个重载来用std::unique_ptr重载替换*this的托管 object,这意味着添加到std::unique_ptr的 API 的另一种本质上的方式执行移动分配,移动分配操作应该受到青睐(语义上)的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM