亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何將唯一_PTR參數傳遞給構造函數或函數?

如何將唯一_PTR參數傳遞給構造函數或函數?

C++
慕無忌1623718 2019-07-03 11:02:22
如何將唯一_PTR參數傳遞給構造函數或函數?我剛開始在C+11中移動語義,我不太清楚如何處理unique_ptr構造函數或函數中的參數??紤]這個類引用自身:#include <memory>class Base{   public:     typedef unique_ptr<Base> UPtr;     Base(){}     Base(Base::UPtr n):next(std::move(n)){}     virtual ~Base(){}     void setNext(Base::UPtr n)     {       next = std::move(n);     }   protected :     Base::UPtr next;};我應該這樣寫函數嗎unique_ptr爭吵?我需要用std::move在電話密碼里?Base::UPtr b1;Base::UPtr b2(new Base());b1->setNext(b2); //should I write b1->setNext(std::move(b2)); instead?
查看完整描述

3 回答

?
楊__羊羊

TA貢獻1943條經驗 獲得超7個贊

以下是將唯一指針作為參數的可能方法,以及它們的相關含義。

(A)按價值計算

Base(std::unique_ptr<Base> n)
  : next(std::move(n)) {}

為了讓用戶調用它,他們必須執行以下操作之一:

Base newBase(std::move(nextBase));Base fromTemp(std::unique_ptr<Base>(new Base(...));

通過值獲取唯一指針意味著轉移指向有關函數/對象/etc的指針的所有權。后newBase被建造,nextBase保證空空..你不擁有這個對象,你甚至沒有指向它的指針。它不見了。

這是確保的,因為我們采用了參數的值。std::move實際上移動什么都行,只是個花哨的演員而已。std::move(nextBase)返回Base&&的r值引用。nextBase..這就是它所能做的。

因為Base::Base(std::unique_ptr<Base> n)根據值而不是r值引用它的論點,C+將自動為我們構造一個臨時的。它創建一個std::unique_ptr<Base>Base&&我們通過std::move(nextBase)..實際上,這個臨時的建筑移動nextBase函數參數n.

(B)非Const l值參考

Base(std::unique_ptr<Base> &n)
  : next(std::move(n)) {}

這必須在實際的l-值(一個命名變量)上調用。不能用這樣的臨時方式調用它:

Base newBase(std::unique_ptr<Base>(new Base)); //Illegal in this case.

它的含義與任何其他非const引用的含義相同:函數可以也可能不會聲明指針的所有權。鑒于此代碼:

Base newBase(nextBase);

不能保證nextBase是空的。它可以,可能是空的;它可能不是。這真的取決于什么Base::Base(std::unique_ptr<Base> &n)想做什么。因此,僅僅從函數簽名中可以看出將要發生的事情并不是很明顯;您必須閱讀實現(或相關的文檔)。

因此,我不建議把它作為一個接口。

(C)由Const l-

Base(std::unique_ptr<Base> const &n);

我沒有顯示一個實現,因為你不可能從一個const&..通過一個const&,您是說函數可以訪問Base通過指針,但它不能商店任何地方。它不能聲稱擁有它的所有權。

這可能很有用。不一定適合你的具體情況,但總能給某人一個指針,并且知道他們不可能(不違反C+的規則,就像沒有拋棄const)聲稱擁有它的所有權。他們不能儲存。他們可以把它傳給別人,但其他人必須遵守同樣的規則。

(D)按r-

Base(std::unique_ptr<Base> &&n)
  : next(std::move(n)) {}

這與“非Const l-value Reference”的情況大致相同。區別是兩件事。

  1. 你,你們能,會,可以臨時通過:

    Base newBase(std::unique_ptr<Base>(new Base)); //legal now..
  2. 你,你們使用std::move在傳遞非臨時參數時。

后者才是真正的問題。如果你看到這一行:

Base newBase(std::move(nextBase));

你有一個合理的期望,在這一行完成之后,nextBase應該是空的。它應該被移開的。畢竟,你有std::move坐在那里告訴你運動已經發生了。

問題是它沒有。它不是被移出。它可以,可能已被移除,但您只能通過查看源代碼才能知道。您不能只從函數簽名中分辨出來。

建議

  • (A)按價值計算:

    如果你想讓一個函數聲稱

    所有權

    一種

    unique_ptr

    用價值來衡量。
  • (C)Const l-參考價值:

    如果您的意思是讓一個函數簡單地使用

    unique_ptr

    在該函數執行期間,請按

    const&

    ..或者,傳遞一個

    &

    const&

    指向的實際類型,而不是使用

    unique_ptr.

  • (D)按r值計算:

    如果一個函數可以或不聲明所有權(取決于內部代碼路徑),那么請通過

    &&

    ..但我強烈建議不要在可能的情況下這樣做。

如何操作UNIQUE_PTR

您不能復制unique_ptr..你只能移動它。正確的方法是使用std::move標準圖書館功能。

如果你unique_ptr從價值上說,你可以自由地離開它。但實際上并不是因為std::move..采取以下聲明:

std::unique_ptr<Base> newPtr(std::move(oldPtr));

這實際上是兩種說法:

std::unique_ptr<Base> &&temporary = std::move(oldPtr);std::unique_ptr<Base> newPtr(temporary);

(注意:上面的代碼沒有技術上的編譯,因為非臨時的r值引用實際上不是r值.)它在這里只是為了演示的目的)。

這個temporary的r值引用。oldPtr..它在構造器newPtr運動發生的地方。unique_ptr的移動構造函數(接受&&對自己來說)是什么實際的運動。

如果你有unique_ptr如果你想把它藏在某個地方,你使用std::move去做儲藏室。


查看完整回答
反對 回復 2019-07-03
?
ITMISS

TA貢獻1871條經驗 獲得超8個贊

是的,如果你拿了unique_ptr構造函數中的值。解釋是件好事。自unique_ptr不可復制(私有副本ctor),您所寫的應該會給您一個編譯器錯誤。


查看完整回答
反對 回復 2019-07-03
  • 3 回答
  • 0 關注
  • 417 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號