[英]What is the difference between std::move and unique_ptr::release?
I am wondering why pstr2 is not null at the 4th line of STDOUT.我想知道为什么 pstr2 在 STDOUT 的第 4 行不是 null。 AFAIK, move and release do not have ownership after a call. AFAIK,移动和释放在通话后没有所有权。
auto pstr = make_unique<string>(5, '*');
cout << (pstr ? *pstr : "pstr is empty") << endl;
auto pstr2(pstr.release());
cout << (pstr ? *pstr : "pstr is empty") << endl;
cout << (pstr2 ? *pstr2 : "pstr2 is empty") << endl;
auto pstr3(move(pstr2));
cout << (pstr2 ? *pstr2 : "pstr2 is empty") << endl;
cout << (pstr3 ? *pstr3 : "pstr3 is empty") << endl;
The output is output 是
*****
pstr is empty
*****
***** <-- my curious part.
*****
When you declare a variable as auto
for its type, its actual type is deduced from whatever value is assigned to the variable during its initialization.当您将变量声明为其类型的auto
时,其实际类型是从在其初始化期间分配给该变量的任何值推导出来的。
The type of pstr
is deduced as unique_ptr<string>
, because that is what make_unique<string>(5, '*')
returns. pstr
的类型被推断为unique_ptr<string>
,因为那是make_unique<string>(5, '*')
返回的内容。
auto pstr2(pstr.release());
does not do what you think it does.不做你认为它做的事。 release()
does not return a unique_ptr<string>
, like you are expecting. release()
不会像您期望的那样返回unique_ptr<string>
。 It returns the raw string*
pointer that was being held by pstr
.它返回pstr
持有的原始string*
指针。 So, the type of pstr2
is deduced as string*
, not as unique_ptr<string>
(and since pstr
has given up its ownership of its string*
pointer, you need to explicitly call delete pstr2;
when you are done, or else the string
object will be leaked).因此, pstr2
的类型被推断为string*
,而不是unique_ptr<string>
(并且由于pstr
已经放弃了对其string*
指针的所有权,因此您需要显式调用delete pstr2;
完成后,否则string
object 会泄露)。
Similar with auto pstr3(move(pstr2));
类似于auto pstr3(move(pstr2));
. . Since pstr2
is a raw string*
, and std::move()
is just a copy for a raw pointer, the type of pstr3
is also deduced as string*
, not as unique_ptr<string>
.由于pstr2
是原始string*
,而std::move()
只是原始指针的副本,因此pstr3
的类型也被推断为string*
,而不是unique_ptr<string>
。 pstr2
and pstr3
are pointing at the same string
object in memory, which is why neither of them are null, and both output the same data to the console. pstr2
and pstr3
are pointing at the same string
object in memory, which is why neither of them are null, and both output the same data to the console.
If you change the type of pstr2
to replace the auto
with unique_ptr<string>
explicitly (or decltype(pstr)
), then you will get the behavior you are expecting, eg:如果您更改pstr2
的类型以明确地将auto
替换为unique_ptr<string>
(或decltype(pstr)
),那么您将获得您期望的行为,例如:
auto pstr = make_unique<string>(5, '*');
cout << (pstr ? *pstr : "pstr is empty") << endl;
unique_ptr<string> pstr2(pstr.release());
// or: decltype(pstr) pstr2(pstr.release());
cout << (pstr ? *pstr : "pstr is empty") << endl;
cout << (pstr2 ? *pstr2 : "pstr2 is empty") << endl;
auto pstr3(move(pstr2));
// or: decltype(pstr2) pstr3(move(pstr2));
cout << (pstr2 ? *pstr2 : "pstr2 is empty") << endl;
cout << (pstr3 ? *pstr3 : "pstr3 is empty") << endl;
Output Output
***** pstr is empty ***** pstr2 is empty *****
I think you are assuming that pstr.release()
returns a std::unique_ptr
whereas in the code as written it returns a std::string *
.我认为您假设pstr.release()
返回一个std::unique_ptr
而在编写的代码中它返回一个std::string *
。 Since this cannot be moved from, this explains the results you get.由于这不能被移动,这解释了你得到的结果。
If you change:如果你改变:
auto pstr2(pstr.release());
to:至:
auto pstr2 = unique_ptr<string>(pstr.release());
then you get the results you expect.然后你会得到你期望的结果。
Because pstr.release() returns a raw pointer, then pstr2 & pstr3 are deducated as raw pointers.因为 pstr.release() 返回一个原始指针,所以 pstr2 和 pstr3 被推导出为原始指针。
After compiling they are just like编译后它们就像
unique_ptr<string> pstr = make_unique<string>(5, '*');
string* pstr2(pstr.release());
string* pstr3(move(pstr2));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.