【问题标题】:RAII and C++ STLRAII 和 C++ STL
【发布时间】:2010-03-05 07:26:37
【问题描述】:

我有一个案例,我希望将资源列表存储在 std::vector 中。在我看来,我的选择如下:

  1. 给我的资源一个默认构造函数
  2. 将它们存储为堆对象(并将它们包装在共享指针中)

选项 1 可以构造无效资源,选项 2 迫使我使用堆。

我是否在这里遗漏了任何选项?

【问题讨论】:

  • 为什么要给资源默认ctor? vector 只需要复制 ctor。
  • "选项 2 强制我使用堆" - 好吧,向量也会将其内容存储在堆中(除非您使用自定义分配器),尽管在连续内存中。因此,您将无法以一种或另一种方式绕过使用堆。
  • 发现我在资源中存储了一个引用,所以问题不是默认构造函数,thx
  • @Naveen:资源的问题是您通常不希望它们具有复制语义。

标签: c++ stl raii


【解决方案1】:

您不需要默认构造函数来拥有实例向量。

唯一的限制是当类没有默认构造函数时,你不能使用带有默认参数的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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 2011-03-22
        • 1970-01-01
        • 2011-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-20
        • 2010-09-28
        相关资源
        最近更新 更多