C++ unique_ptr:移动任务所有权并自动释放资源
通过一个任务对象观察唯一所有权、移动后的空指针和作用域退出时自动释放资源,避免重复释放与移动后误用。
本节目标
通过一个任务对象观察唯一所有权、移动后的空指针和作用域退出时自动释放资源,避免重复释放与移动后误用。
环境与运行方法
使用 C++17 编译器,保存为 lesson.cpp,执行 c++ -std=c++17 -Wall -Wextra -Werror lesson.cpp -o lesson 后运行 ./lesson。以下仅使用标准库。
核心思路
RAII 将资源释放绑定到管理对象的生命周期。unique_ptr 禁止普通复制,表明同一资源不能被两个独立的唯一所有者同时持有。make_unique 创建对象并立即交给管理器。
完整示例
#include <iostream>
#include <memory>
#include <string>
#include <utility>
struct Task { std::string title; bool done = false; };
int main() {
auto task = std::make_unique<Task>(Task{"review", false});
task->done = true;
auto owner = std::move(task);
std::cout << "old=" << (task ? "owns" : "empty") << '\n';
std::cout << owner->title << ':' << owner->done << '\n';
}预期输出
old=empty
review:1逐步理解
移动后 owner 拥有原任务,task 变为空。对象内容没有丢失,所以仍显示 review 与完成状态。程序退出作用域时 owner 释放任务,不需要手写 delete。
如果另一个函数只读取任务,用 const Task& 借用即可;只有交出生命周期管理责任时才移动 unique_ptr。共享访问不必然要求 shared_ptr,共享所有权需要更明确的设计理由。
常见问题与边界
- 移动后不能继续解引用旧指针。
- 不要让两个 unique_ptr 管理同一个裸指针。
- std::move 本身是转换,实际转移行为由目标类型的移动操作完成。
动手练习
移动前复制标题作为日志,移动后把 owner 的标题改成 done。
参考答案
日志字符串仍为 review,owner 的标题变为 done,旧 task 仍为空。值副本、资源内容和所有权是三个可以独立观察的层面。
文章回复
0 条公开回复