首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么std::unique_ptr重置不等同于赋值?

为什么std::unique_ptr重置不等同于赋值?
EN

Stack Overflow用户
提问于 2018-05-03 11:11:54
回答 2查看 2.7K关注 0票数 11

我在试着理解为什么

代码语言:javascript
复制
std::unique_ptr<MyClass> p = new MyClass; 

不起作用,但是

代码语言:javascript
复制
std::unique_ptr<MyClass> p;
p.reset(new MyClass);

很好。我有点理解它们的不同之处,但我想知道为什么做出这样的选择是为了让它们不同。赋值不同于重置有什么危险?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-03 11:17:18

首先,std::unique_ptr<MyClass> p = new MyClass;不是赋值,它是copy initialization。它不能工作,因为接受原始指针的constructor of std::unique被标记为explicit

显式unique_ptr(指针p)不例外;

它被声明为explicit,以避免意外的(可能是危险的)隐式转换,例如:

代码语言:javascript
复制
void foo(std::unique_ptr<int> uptr);

int *rptr = new int;
foo(rptr); // suppose rptr is implicitly converted to std::unique_ptr<int>
           // then the ownership is passed to the parameter uptr

// when foo() returns uptr is destroyed; the pointer managed by it is deleted too
// since rptr has been deleted continue to deference on it leads to UB
*rptr = 42; // UB

请注意,copy initialization中不考虑explicit构造函数(例如std::unique_ptr<MyClass> p = new MyClass;)。你可以在direct initialization中使用它们(例如std::unique_ptr<MyClass> p (new MyClass);)。它们用于禁止隐式转换,但您可以执行显式转换。就像reset的用法一样,你必须显式地()做这些事情,以显示(并让你自己)你非常确定你在做什么。

顺便说一下:来自原始指针的赋值也不起作用,因为std::unique_ptr没有将原始指针作为参数的重载赋值运算符。由于上述原因,原始指针不能被隐式转换为std::unique_ptr,因此移动赋值操作符(以std::unique_ptr为参数)也不会被考虑。

票数 20
EN

Stack Overflow用户

发布于 2018-05-03 11:23:32

我想知道为什么std::unique_ptr<MyClass> p = new MyClass;不能工作

与@songyuanyao提到的被声明为explicit的原因相同,这表明您仍然可以在比explicit更好的a form of initialization中初始化它

代码语言:javascript
复制
// Valid, since now it's 'explicit'
std::unique_ptr<MyClass> p { new MyClass{} };
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50146366

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档