将对象引用存储在一个简单的容器中

Mih*_*dor 0 c++ containers pointers stl reference

我正在寻找一种方法A在容器对象内插入多个类型的对象,而不是A在插入过程中复制每个对象.一种方法是A通过引用传递对象,但不幸的是,据我所知,STL容器只接受按插值的值传递对象(出于很多好的理由).通常情况下,这不是问题,但在我的情况下,我不希望调用复制构造函数并将原始对象销毁,因为它A是C库的包装器,其中包含一些C语言指针到内部结构,将与原始对象一起删除...

给定一个特定的索引,我只需要一个可以返回其中一个对象的容器,并存储一定数量的在运行时确定的项目,所以我想也许我可以编写自己的容器类,但我不知道如何这样做得恰到好处.

另一种方法是将指针存储A在容器内部,但由于我对这个主题没有太多的知识,在STL容器中插入指向对象的指针是什么?例如:

std::vector<A *> myVector;
for (unsigned int i = 0; i < n; ++i)
{
    A *myObj = new myObj();
    myVector.pushBack(myObj);
}
Run Code Online (Sandbox Code Playgroud)

可能有用,但我不确定如何正确处理它以及如何以干净的方式处理它.我应该完全依赖包含myVector的类的析构函数来处理它吗?如果此析构函数在删除其中一个包含的对象时抛出异常会发生什么?

此外,有些人建议使用像shared_ptrauto_ptr或类似的东西unique_ptr,但我对这么多的选择感到困惑.哪一个是我的方案的最佳选择?

pmr*_*pmr 5

你可以使用booststd reference_wrapper.

#include <boost/ref.hpp>
#include <vector>

struct A {};


int main()
{
  A a, b, c, d;
  std::vector< boost::reference_wrapper<A> > v;
  v.push_back(boost::ref(a)); v.push_back(boost::ref(b)); 
  v.push_back(boost::ref(c)); v.push_back(boost::ref(d));
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

在使用reference_wrapper不得悬挂引用时,您需要了解对象的生命周期 .

int main()
{
  std::vector< boost::reference_wrapper<A> > v;
  {
    A a, b, c, d;
    v.push_back(boost::ref(a)); v.push_back(boost::ref(b)); 
    v.push_back(boost::ref(c)); v.push_back(boost::ref(d));
    // a, b, c, d get destroyed by the end of the scope
  }
  // now you have a vector full of dangling references, which is a very bad situation
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果你需要处理这种情况,你需要一个智能指针.

智能指针也是一种选择,但知道使用哪一个是至关重要的.如果您的数据实际上是共享的,shared_ptr请在容器拥有数据使用时使用unique_ptr.

无论如何,我不知道包装部分A会改变什么.如果它内部包含指针并遵守三条规则,那么什么都不会出错.析构函数将负责清理.这是在C++中处理资源的典型方法:在初始化对象时获取它们,在对象的生命周期结束时删除它们.

如果你纯粹想要避免构造和删除的开销,你可能想要使用vector::emplace_back.