【问题标题】:STL: Stores references or values?STL:存储引用或值?
【发布时间】:2009-09-05 06:29:28
【问题描述】:

我一直对 STL 容器(向量、列表、地图...)如何存储值感到有些困惑。他们是存储对我传入的值的引用,还是他们自己复制/复制构造+存储值?

例如,

int i;
vector<int> vec;
vec.push_back(i);
// does &(vec[0]) == &i;

class abc;
abc inst;
vector<abc> vec;
vec.push_back(inst);
// does &(vec[0]) == &inst;

谢谢

【问题讨论】:

  • 您已经得到了在我看来可以测试答案的工作代码(稍作更改以使评论成为有条件的)。运行它看看!我很确定他们会复制构建和存储。

标签: c++ stl reference vector


【解决方案1】:

STL Containers 复制构造并存储您传入的值。如果您想将对象存储在容器中而不复制它们,我建议在容器中存储指向该对象的指针:

class abc;
abc inst;
vector<abc *> vec;
vec.push_back(&inst);

这是实现容器类的最合乎逻辑的方式,以防止意外地将对已失效堆栈帧上的变量的引用存储。考虑:

class Widget {
public:
    void AddToVector(int i) {
        v.push_back(i);
    }
private:
    vector<int> v;
};

存储对i 的引用会很危险,因为您会在从定义局部变量的方法返回后引用局部变量的内存位置。

【讨论】:

  • 您不能创建在 C++ 中存储引用的创建容器。传递给容器的类型参数必须是可赋值的。引用是不可分配的,它们是用一个对象初始化的,但在构造后不能分配给一个不同的对象。因此引用类型不满足在容器内使用的类型要求。如果你想拥有相同的语义(或尽可能接近),你必须提供一个引用包装器(boost::ref/boost::cref)
  • @dribeas:这个答案通过解释假设实施的风险来解释为什么不
【解决方案2】:

这取决于您的类型。如果它是一个简单的值类型,并且复制起来很便宜,那么存储值可能就是答案。另一方面,如果它是引用类型,或者复制成本很高,则最好存储一个智能指针(不是 auto_ptr,因为它的特殊复制语义会阻止它存储在容器中。去找一个 shared_ptr)。使用普通指针,您将冒着内存泄漏和访问已释放内存的风险,而使用引用则冒着后者的风险。智能指针可以避免两者。

【讨论】:

  • +1 关于在容器内使用智能指针来处理内存。另一种选择是使用像 Boost Pointer Container 这样的库来处理资源释放
  • 这不是 OP 所要求的。他想知道容器类本身是否在将值放入容器时复制该值。答案是,是的,它们确实如此——这就是为什么如果所讨论的特定类型的复制成本很高,那么存储指针可能会很好。
  • 如果您知道自己在做什么并自己清理,那么存储裸指针是非常好的。
猜你喜欢
  • 1970-01-01
  • 2018-07-29
  • 2014-08-25
  • 1970-01-01
  • 1970-01-01
  • 2017-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多