缺少unique_ptr和friends运算符=重载

Missing unique_ptr and friends operator= overload

本文关键字:运算符 重载 friends unique ptr 缺少      更新时间:2023-10-16

我知道这类问题在这里并不受欢迎,但我必须问:为什么unique_ptr/shared_ptr/etc没有类型t的运算符=重载?

写似乎更自然

std::unique_ptr<int> p = new int(5);

而不是

std::unique_ptr<int> p(new int(5));

或任何其他更详细的方法。

如果允许您编写以下内容:

std::unique_ptr<int> p = new int(5);

然后你也可以写这些:

void Func1(std::unique_ptr<int> p);
Func1(new int(5));
std::unique_ptr<int> Func2() {return new int(5);}

或者更危险的:

void Func1(std::unique_ptr<int> p);
int *pInt = new int(5);
Func1(pInt); //You no longer own the pointer anymore.
delete pInt; //You're now deleting a pointer you don't own.

出于显而易见的原因,这是不可接受的。他们不希望从裸指针到唯一指针的隐式转换;如果你想创建一个unique_ptr,你必须明确:Func1(std::unique_ptr<int>(pInt));现在,每个人都可以看到你正在将所有权从自己转移到函数。

此外,它不是一个operator=会使这个工作。正是unique_ptr的单参数构造函数上的explicit阻止了复制初始化语法的工作。

您所指的是unique_ptr<T>的构造函数采用原始T指针是显式。这是经过深思熟虑的。唯一的指针拥有所有权,这不应该隐式发生。用户应该始终明确知道所有权何时创建、转移和终止。

在一个更严厉的世界里,人们可以想象unique_ptr根本不接受任何原始指针,而是只允许直接创建所拥有的对象:

auto p = std::unique_ptr<T>::make(arg1, arg2, arg3);
                             // Calls "new T(arg1, arg2, arg3)".
                             // Not real code.