RAII and C++ STL

5

我有一个问题,需要在std::vector中存储资源列表。我看到的选择有以下几种:

  1. 为我的资源提供默认构造函数。
  2. 将它们存储为堆对象(并用shared pointer包装)。

选项1可以构建无效的资源,而选项2则强制我使用堆。

这里是否还有其他选择?


1
为什么要给资源默认构造函数?vector 只需要复制构造函数。 - Naveen
2
"选项2强制我使用堆" - 好吧,向量也会将其内容存储在堆上(除非您使用自定义分配器),尽管是在连续的内存中。因此,您无论如何都无法避免使用堆。 - Johann Gerell
发现我在资源中存储了一个引用,所以问题不是默认构造函数,谢谢。 - Dirk
1
@Naveen:资源的问题在于你通常不希望它们具有复制语义。 - Emile Cormier
3个回答

7

您不需要默认构造函数就可以拥有实例的向量。

唯一的限制是当类没有默认构造函数时,您不能使用带有默认参数的vector :: resize。

vec.resize(20);  // requires default constructor

但是你可以给 vector::resize 一个默认对象:

std::vector<foo> vec;
vec.resize(20, foo(10));  // give a sample object since foo has not default constructor

1

您可以在向量中存储具有非平凡构造函数的对象。存储在STL容器中的对象应具有赋值语义(复制构造函数和赋值运算符)。


1

第三个选择是使用Boost.PointerContainer。但是,您的对象仍将在堆上单独分配。正如Johann所评论的那样,std::vector已经利用堆来存储对象(连续的),因此无法完全避免堆。

通常不允许资源(例如互斥锁、I/O流等)具有复制语义。因此,必须通过将复制构造函数和赋值运算符设置为私有来使它们不可复制。不幸的是,不可复制的限制使得无法直接将资源作为值存储在STL容器内。因此,必须采用Boost.PointerContainer或智能指针容器。 Boost.PointerContainer文档中的动机部分解释了为什么您更喜欢使用其中之一。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接