You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++20下向std::vector<unique_ptr<Object>>添加元素的最优安全方式

向存储std::unique_ptr<Object>的std::vector添加元素的最优安全方案

首先明确:绝对要避免的写法

vec.emplace_back(new Object) 这种写法存在内存泄漏风险,是不安全的。原因是:当vector需要扩容时,会先尝试分配新内存,如果分配失败抛出异常,此时new Object已经创建了对象,但std::unique_ptr还没完成构造,无法接管对象所有权,导致对象内存直接泄漏。

合规且安全的核心方案

所有安全方案的核心都是让std::unique_ptr立刻接管新创建的Object,避免裸指针暴露的风险。优先使用std::make_unique(C14及以上支持,你的G11.1.0完全兼容):

1. 使用std::make_unique配合emplace_back或push_back

这两种写法在C++20下效率几乎无差异,都是安全的:

  • vec.emplace_back(std::make_unique<Object>());
    emplace_back会完美转发std::make_unique返回的右值unique_ptr,原地移动构造vector中的元素,无额外拷贝开销。
  • vec.push_back(std::make_unique<Object>());
    push_back接受右值引用,同样会移动构造元素,效果和上面一致。

如果Object需要构造参数,直接传递给make_unique即可:

vec.emplace_back(std::make_unique<Object>(arg1, arg2));

2. 仅添加空unique_ptr的场景

你提到的vec.emplace_back()是完全合规的,它会默认构造一个空的std::unique_ptr<Object>(指向nullptr)。但注意这种写法不会创建任何Object实例,仅适用于需要添加空智能指针的场景。

emplace_back vs push_back的选择

在C++20中,对于std::unique_ptr这类仅支持移动语义的类型:

  • 当传递右值(比如std::make_unique的返回值)时,emplace_back和push_back的效率完全一致,都是移动构造元素,没有性能差异。
  • emplace_back的优势在于可以原地构造元素,但对于unique_ptr来说,直接传递裸指针会回到泄漏风险,所以还是配合make_unique使用更安全。

总结:优先选择std::make_unique配合emplace_back或push_back,两者都是最优且安全的写法,根据个人习惯选择即可。

内容的提问来源于stack exchange,提问作者spaL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 04:39:19