← 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。

当代码中显示所有权时,就不用担心何时删除。