我正在寻找一种在容器对象中插入多个 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);
}
可能有用,但我不确定如何正确处理它以及如何以干净的方式处理它。我是否应该仅依靠包含 myVector 作为成员的类的析构函数来处理它?如果此析构函数在删除其中一个包含的对象时抛出异常,会发生什么情况?
此外,有些人建议使用像 shared_ptr
或 auto_ptr
或 unique_ptr
这样的东西,但我对这么多选项感到困惑。哪个是我的场景的最佳选择?
最佳答案
您可以使用boost
或std
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;
}
使用时需要注意对象的生命周期
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;
}
如果你需要处理这种情况,你需要一个智能指针。
智能指针也是一种选择,但了解使用哪一个是至关重要的。如果您的数据实际上是共享的,请使用 shared_ptr
如果容器拥有数据则使用 unique_ptr
。
无论如何,我看不到 A
的包装器部分会发生什么变化。如果它内部包含指针并遵守 rule of three , 什么都不会出错。析构函数将负责清理。这是在 C++ 中处理资源的典型方式:在对象初始化时获取它们,在对象的生命周期结束时删除它们。
如果您纯粹想避免构造和删除的开销,您可能需要使用 vector::emplace_back
。
关于c++ - 在简单容器中存储对象引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11104337/