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

添加至C++ std::set的对象副本作用域及存储方式疑问

关于std::set中元素生命周期与存储方式的问题

场景代码

全局作用域的集合定义:

std::set<Person> people;

添加元素的函数:

void addEntry() {
    Person p1("kosh", 55);
    people.emplace(p1);
}

用户疑问

  1. 已知添加时会创建p1的副本(拷贝构造函数被调用),函数结束后p1会销毁,那集合中这个副本的生命周期由什么决定?是不是和集合的作用域绑定?
  2. 补充问题:这种场景下,是不是在堆上创建p1然后把指针存到集合里更好?

回答

关于集合中副本的生命周期

集合people是全局变量,它内部存储的所有元素(包括你添加的p1副本)的生命周期完全由集合本身决定:

  • 只要集合people存在(全局变量会存活到程序终止),里面的元素就会一直存在;
  • 只有当你主动调用people.erase()移除该元素,或者调用people.clear()清空集合,或者程序结束时,这个副本才会被销毁。
    函数里的p1销毁和集合里的副本完全没关系,二者是独立的对象。

关于是否改用堆存储+指针集合

完全没必要,优先用值存储的方式更合适,原因如下:

  • 内存管理更简单:std::set会自动管理内部元素的内存,不用你手动new/delete,从根源避免内存泄漏;
  • 复杂度更低:如果存原始指针,你得自己跟踪每个指针的生命周期,稍不注意就会出现野指针或者内存泄漏;用智能指针(比如std::shared_ptr)虽然能解决内存问题,但会额外增加引用计数的开销和代码复杂度;
  • 访问效率更高:值存储的元素直接在集合的内存结构里,访问时不需要解引用指针,减少了内存间接访问的开销;
  • 只有特殊场景才需要指针:比如Person对象特别大,拷贝成本极高,或者需要在多个容器之间共享同一个Person对象的所有权,这时才考虑用指针(配合智能指针)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 13:53:12