C++ 從基礎到精通 — 第 9 講
用智慧指針表達所有權
該部落格上撰寫的文章是出於教學目的而創建的。 另外,文章中的資訊可能不正確,請謹慎。
使用指針不會造成問題。 當原始指標被用作所有權而不知道誰應該銷毀該物件時,就會出現問題。
智慧型指標將所有權表示為一種類型。
unique_ptr
std::unique_ptr擁有獨家所有權。
#include <memory>
auto warrior = std::make_unique<Warrior>("Rose");
std::cout << warrior->Attack() << '\n';
不直接呼叫newstd::make_unique創建一個對象 如果 unique_ptr 超出範圍,則擁有的物件將自動銷毀。
由於它是獨佔的,因此無法複製,但可以移動。
std::vector<std::unique_ptr<Character>> party;
auto warrior = std::make_unique<Warrior>("Rose");
party.push_back(std::move(warrior));
std::move之後,戰士變成空,所有權轉移到向量。 std::move 本身將其視為可移動值,而不是移動物件的函數。
shared_ptr
單一怪物可能需要同時屬於活動清單和戰鬥系統。 此時std::shared_ptr可以使用。
auto monster = std::make_shared<Monster>(1, "Slime", 30);
std::vector<std::shared_ptr<Monster>> activeMonsters;
std::queue<std::shared_ptr<Monster>> spawnQueue;
spawnQueue.push(monster);
activeMonsters.push_back(monster);
當shared_ptr被複製時,物件並沒有被複製,但是它的引用計數會增加。 當它的最後一個所有者消失時,實際的物件就會被銷毀。
僅僅為了方便而將所有指標放入shared_ptr並不是一個好主意。 誰擁有它變得不清楚,可能會發生循環引用,並且存在引用計數管理成本。
weak_ptr
如果您不擁有像當前目標這樣的物件並且只想觀察它,std::weak_ptr使用 。
std::weak_ptr<Monster> currentTarget;
currentTarget = monster;
if (auto target = currentTarget.lock())
{
std::cout << target->GetHealth() << '\n';
}
weakptr 不會延長物件的生命週期。 如果目標還活著lock()傳回此sharedptr,或者如果它已經被銷毀,則傳回一個空的shared_ptr。
總結一下,如果只有一個所有者 uniqueptr, 如果多個系統確實需要擁有sharedptr, 如果你只是查看而不擁有它,那麼它就是weak_ptr。
當程式碼中顯示所有權時,就不用擔心何時刪除。