0Pricing
C++ Academy · 课时

陷阱与生命周期

避免悬空视图

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

视图不拥有数据

string_view 只指向由其他对象拥有的字符。如果那段存储消失,视图就会悬空,访问它会产生未定义行为。

从临时对象产生悬空视图

将视图绑定到临时的 std::string 很危险:临时对象会在语句末尾销毁,使视图指向已释放的内存。

#include <string>
#include <string_view>
std::string make() { return "temp"; }
int main() {
    std::string_view sv = make(); // dangles immediately
    // using sv here is undefined behavior
    (void)sv;
}

返回指向局部对象的视图

绝不要返回指向局部字符串内部的视图;函数返回时,局部字符串就会被销毁。

#include <string>
#include <string_view>
std::string_view bad() {
    std::string local = "oops";
    return local; // local dies, view dangles
}
int main() { (void)bad(); }

安全情况:指向仍存活字符串的视图

只要源对象的生命周期长于视图,使用视图就是安全的。在这里,字符串会在整个函数期间保持存在。

#include <iostream>
#include <string>
#include <string_view>
int main() {
    std::string s = "alive";
    std::string_view sv = s;
    std::cout << sv << "\n"; // safe
}

不保证以空字符结尾

视图中的数据不保证以 \0 结尾。将 sv.data() 传给要求 C 字符串的 C 函数,可能会导致函数读取末尾之后的内容。

使用 size(),不要使用 strlen

请始终使用 sv.size() 获取长度,而不要依赖 C 字符串函数,因为视图可能只是较大缓冲区中的一段切片。

#include <iostream>
#include <string_view>
int main() {
    std::string_view sv = std::string_view("hello world").substr(0, 5);
    std::cout << sv.size() << "\n"; // 5, not 11
}

修改源对象

如果底层字符串重新分配了内存(例如 push_back 导致容量增长),现有的指向其中的视图就会失效。

将视图存储为成员

将 string_view 存储为类成员时请务必谨慎;您必须保证被引用的数据生命周期长于对象。不确定时,请改为存储 std::string。

参数通常是安全的

将 string_view 用作函数参数是安全且符合惯用法的场景:实参的生命周期会长于这次调用。

#include <iostream>
#include <string_view>
size_t len(std::string_view sv) { return sv.size(); }
int main() {
    std::cout << len("temporary is fine here") << "\n";
}

必须持久保存时进行复制

如果您需要在源对象的生命周期结束后继续保留文本,请将其复制到 std::string 中。复制就是拥有数据所需付出的代价。

#include <string>
#include <string_view>
std::string keep(std::string_view sv) {
    return std::string(sv); // owns a copy
}
int main() { (void)keep("persist"); }

经验法则

参数和生命周期较短的局部对象优先使用 string_view。除非数据的生命周期明确更长,否则不要将它用作返回类型或长期存在的成员。

快速检查

检查您对视图生命周期的理解。

回顾

您学习了视图的陷阱和生命周期:

  • 视图不拥有数据;源对象的生命周期必须长于视图。
  • 避免让视图指向临时对象和局部对象。
  • 视图不保证以空字符结尾,请使用 size()。
  • 需要持久保存文本时,请将其复制到 std::string 中。

常见问题解答

「陷阱与生命周期」课时是免费的吗?

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

「陷阱与生命周期」这节课中我会学到什么?

避免悬空视图 你通过在浏览器中直接运行的动手代码来练习 C++ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

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

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

「陷阱与生命周期」课时需要多长时间?

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

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

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

此课程中的所有课时

  1. 为什么使用 string_view
  2. 创建视图
  3. 陷阱与生命周期
  4. 字符串算法
← 返回 C++ Academy