0Pricing
C++ Academy · 课时

引用的生命周期与悬空引用

仔细分析对象的生命周期,避免产生悬空引用

引用的生命周期与悬空引用 是 CoddyKit 上的免费 C++ Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C++ Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C++ Academy 课程共包含 4 节课。

什么是悬空引用

当引用所指向的对象已被销毁时,引用就会变成悬空引用。使用它属于未定义行为,任何情况都有可能发生。

经典示例

返回局部变量的引用。局部变量会在函数返回时销毁;调用方持有的引用会指向已失效的内存。

// BUG
int& bad() {
    int x = 10;
    return x;       // x dies here
}

int& r = bad();
std::cout << r;     // UB

对容器元素的引用

如果 std::vector 重新分配内存,指向其中元素的引用就会变成悬空引用。添加元素可能会移动全部存储空间。

std::vector<int> v = {1, 2, 3};
int& r = v[0];
v.push_back(99);    // may reallocate
std::cout << r;     // possibly UB

对映射和列表中元素的引用

某些容器(std::list、std::map,以及未受影响节点的 std::unordered_map)会提供稳定的迭代器和引用。std::vector 和 std::deque 则不会。

临时对象的生命周期规则

const 引用会延长临时对象的生命周期,但返回该引用的函数不会进一步延长它的生命周期。

// Subtle BUG
const std::string& f() {
    return std::string("temp"); // dies at return
}

const std::string& s = f();      // dangling

if-init 语句中的生命周期(C++17)

C++17 if/switch 初始化语句中的变量会一直存在到 if/switch 的主体结束,这很有用,但请注意作用域。

if (const auto& it = map.find(k); it != map.end()) {
    use(it->second);
}
// `it` is dead here

类中的引用成员

将引用存储为类成员会使类的生命周期受被引用对象约束。类永远不能比被引用对象存活得更久。只有在所有权语义确实要求时才使用这种方式。

可选所有权中的 pointer 与引用

引用不能为 null,但如果被引用对象销毁,引用就会失效。Pointer 可以更明确地表示可选或可能悬空的情况。

改用智能指针

对于共享所有权,请使用 std::shared_ptr。只要至少存在一个 shared_ptr,该 pointer 就会使对象保持存活。相关内容将在智能 pointer 课程中介绍。

编译器帮助:lifetimebound

现代编译器(Clang、GCC)会针对某些悬空引用模式发出警告。如果支持,请启用 -Wdangling-reference。

常见惯用法:视图类型

std::string_view 和 std::span 都是非拥有视图。它们与引用存在相同的生命周期问题,也需要同样谨慎地使用。

快速检查

哪种操作可能使指向 std::vector 中元素的引用失效?

回顾

引用不会延长或拥有任何对象,它们只是现有对象的别名。如果对象先被销毁,引用就会变成悬空引用。请注意不要返回局部引用,不要忽视容器重新分配,也不要让临时对象的引用长期存在。

常见问题解答

「引用的生命周期与悬空引用」课时是免费的吗?

是的 — 「引用的生命周期与悬空引用」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C++ Academy 课程的其余内容,请升级到 CoddyKit PRO。 C++ Academy 课程共包含 4 节课。

「引用的生命周期与悬空引用」这节课中我会学到什么?

仔细分析对象的生命周期,避免产生悬空引用 你通过在浏览器中直接运行的动手代码来练习 C++ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 C++ Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 C++ Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「引用的生命周期与悬空引用」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 C++ Academy 课中编写并运行代码吗?

能。每节 C++ Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 引用为何是变量的别名
  2. 按值传递与按引用传递
  3. const 引用及其适用场景
  4. 引用的生命周期与悬空引用
← 返回 C++ Academy