能,但必须用 std::move;因 unique_ptr 禁止拷贝,push_back 默认尝试拷贝会编译失败,移动后原指针为空,对象存于堆、vector 仅存指针,缓存不友好。

std::unique_ptr 能不能直接 push_back 到 vector 里?
能,但必须用 std::move,否则编译失败。因为 std::unique_ptr 禁止拷贝,而 vector::push_back 的默认重载会尝试拷贝元素。
常见错误现象:error: use of deleted function 'std::unique_ptr<t>::unique_ptr(const std::unique_ptr<t>&)'</t></t>
- 正确做法:用
vec.push_back(std::move(ptr)),把所有权转移进去 - 如果从函数返回临时
std::unique_ptr,比如make_unique<foo>()</foo>,可直接push_back—— 因为临时对象自动触发移动(无需显式std::move) - 注意:移动后原
ptr变成空(ptr == nullptr),再访问会出错
vector<:unique_ptr>> 的内存布局和性能影响
每个 std::unique_ptr 本身只占一个指针大小(通常 8 字节),vector 存的是这些指针的连续数组,不是对象本体。
- 对象实际分配在堆上,彼此不连续 → 缓存不友好,遍历时比
vector<t></t>慢 - 但插入/删除末尾元素很快(只移动指针,不移动对象)
- 若需频繁随机访问且关心缓存,优先考虑
vector<t></t>或vector<shared_ptr>></shared_ptr>(仅当需要共享所有权)
emplace_back 和 make_unique 怎么配合用才安全?
推荐组合:vec.emplace_back(std::make_unique<t>(args...))</t>,避免中间变量和多余移动。
立即学习“C++免费学习笔记(深入)”;
- 错误写法:
vec.emplace_back(new T(args...))—— 手动new容易忘delete,且不异常安全 -
emplace_back会直接在vector内部构造unique_ptr,跳过临时对象 - 如果
T构造可能抛异常,make_unique保证异常安全:要么全成功,要么不分配
为什么 vector 里存 unique_ptr 后不能用 sort 或 stable_sort?
可以,但必须传自定义比较函数,且不能直接比较 unique_ptr 本身(它只支持 ==/!=/ 等,但语义是地址比较,通常不是你想要的)。
- 常见误用:
std::sort(vec.begin(), vec.end())→ 按指针地址排序,结果不可控 - 正确做法:按所指对象内容排序,例如
std::sort(vec.begin(), vec.end(), [](const auto& a, const auto& b) { return *a - 注意:如果
*a或*b是空指针,解引用会崩溃 —— 必须先判空
最常被忽略的一点:vector<:unique_ptr>></:unique_ptr> 的析构是自动的,但如果你用 reset() 或赋值覆盖某个元素,旧对象会立刻销毁;而整个 vector 被销毁时,所有剩余非空 unique_ptr 也会自动释放 —— 这部分不用管,但得确保没提前裸指针泄露。










