簡體   English   中英

問題通過std :: unique_ptr

[英]Issue passing std::unique_ptr's

在過去的一個小時中一直停留在此代碼上,仍然試圖讓我領悟並實現智能指針,但是這個問題使我很困惑。

void GameState::addEntity(std::unique_ptr<Entity> gameObject)
{
    if(gameObject->isCollidable()){
        _actors.Add(gameObject);
    } else {
        _props.Add(gameObject);
    }
}

// This is the method the above function is trying to call.
void GameObjectManager::Add(std::unique_ptr<Entity> gameObject)
{
    _gameObjects.insert(std::make_pair(ID, std::move(gameObject)));
    ID++;
}

我收到的錯誤消息是;

'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'  

您需要使用std::move將所有權從addEntity傳遞給Add

if(gameObject->isCollidable()){
    _actors.Add(std::move(gameObject));
} else {
    _props.Add(std::move(gameObject));
}

如果未明確允許將其從中移出,則無法傳遞unique_ptr 這就是使其成為唯一指針的原因。 如果可以復制它,則原件和副本都將指向同一對象。 當您離開它時,原始指針將放棄對新指針的所有權。

您正在嘗試將unique_ptr 左值傳遞給按value接受unique_ptr 的函數 ,這將導致創建該指針的副本 :這是有意禁止的。 唯一指針用於對唯一所有權進行建模:這意味着持有唯一指針的實體具有指向對象的所有權。

在周圍復制一個唯一的指針將意味着在系統中散布多個擁有的指針:這當然會破壞唯一所有權的目的,這解釋了為什么您不能復制唯一的指針。

您可以做的是轉移此所有權,因此,如果調用一個接受唯一指針的函數,則可以unique_ptr作為參數傳遞給該函數時移動它:

_actors.Add(std::move(gameObject));
//          ^^^^^^^^^

請注意,通過移離唯一指針來轉移所有權意味着調用者函數被留有“僵屍”唯一指針對象,該對象不再擁有先前指向的對象:因此,調用者函數不應嘗試對其進行取消引用了。

您不能按值傳遞unique_ptr 以下是嘗試創建unique_ptr副本,這是被禁止的:

if(gameObject->isCollidable()){
    _actors.Add(gameObject);     // THIS LINE
} else {
    _props.Add(gameObject);      // and THIS LINE
}

一個解決方案通過std::move()

if(gameObject->isCollidable()){
    _actors.Add(std::move(gameObject));
//              ^^^^^^^^^
} else {
    _props.Add(std::move(gameObject));
//              ^^^^^^^^^
}

這將導致兩次所有權轉移。 一個為std::unique_ptr<Entity> ,它是GameObjectManager::Add的輸入參數,另一個為_gameObjectsstd::pair

另一個解決方案是修改GameObjectManager::Add的簽名以獲取參考:

void GameObjectManager::Add(std::unique_ptr<Entity> & gameObject)
//                                                 ^^^

現在,您可以像現在一樣調用該方法,這將僅導致一次所有權轉移(到_gameObjectspair )。

但是,正如@Xeo在評論中指出的那樣,第二種選擇違反了最佳實踐的經驗法則,即: 所有權轉讓在所有時候都應明確

暫無
暫無

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

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