← SEARCHABLE ARCHIVE
C / C++ · 2026-06-23

C++ 從基礎到精通 — 第 9 講

用智慧指針表達所有權

INTERACTIVE READING MODE →

該部落格上撰寫的文章是出於教學目的而創建的。 另外,文章中的資訊可能不正確,請謹慎。

使用指針不會造成問題。 當原始指標被用作所有權而不知道誰應該銷毀該物件時,就會出現問題。

智慧型指標將所有權表示為一種類型。

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。

當程式碼中顯示所有權時,就不用擔心何時刪除。