簡體   English   中英

std::move 和 unique_ptr::release 有什么區別?

[英]What is the difference between std::move and unique_ptr::release?

我想知道為什么 pstr2 在 STDOUT 的第 4 行不是 null。 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;

output 是

*****
pstr is empty
*****
***** <-- my curious part.
*****

當您將變量聲明為其類型的auto時,其實際類型是從在其初始化期間分配給該變量的任何值推導出來的。

pstr的類型被推斷為unique_ptr<string> ,因為那是make_unique<string>(5, '*')返回的內容。

auto pstr2(pstr.release()); 不做你認為它做的事。 release()不會像您期望的那樣返回unique_ptr<string> 它返回pstr持有的原始string*指針。 因此, pstr2的類型被推斷為string* ,而不是unique_ptr<string> (並且由於pstr已經放棄了對其string*指針的所有權,因此您需要顯式調用delete pstr2;完成后,否則string object 會泄露)。

類似於auto pstr3(move(pstr2)); . 由於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的類型以明確地將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

*****
pstr is empty
*****
pstr2 is empty
*****

現場演示

我認為您假設pstr.release()返回一個std::unique_ptr而在編寫的代碼中它返回一個std::string * 由於這不能被移動,這解釋了你得到的結果。

如果你改變:

auto pstr2(pstr.release());

至:

auto pstr2 = unique_ptr<string>(pstr.release());

然后你會得到你期望的結果。

現場演示

因為 pstr.release() 返回一個原始指針,所以 pstr2 和 pstr3 被推導出為原始指針。

編譯后它們就像

unique_ptr<string> pstr = make_unique<string>(5, '*');
string* pstr2(pstr.release());
string* pstr3(move(pstr2));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM