【问题标题】:Why can't I create a std::stack of std::ifstreams?为什么我不能创建 std::ifstreams 的 std::stack?
【发布时间】:2011-01-22 17:38:51
【问题描述】:

为什么以下方法不起作用:

#include <iostream>
#include <fstream>
#include <stack>

std::stack<std::ifstream> s;

-PT

【问题讨论】:

  • 在 C++0x 中,你将能够。

标签: c++ stl stack iostream ifstream


【解决方案1】:

std::stack(与所有 STL 容器一样)要求其包含的类型是“可分配的”。在 STL 中,这意味着它必须有一个复制构造函数和一个operator=std::ifstream 两者都没有。

您可以想象为什么您不希望能够复制和分配 I/O 流;当同一流有两个副本时应该发生什么的语义并不明显。读取或写入一个副本是否会影响另一个副本的位置?关闭一个流是否应该关闭另一个?等等

如果你想拥有“std::ifstreams 的容器”,那么你真正应该做的是“std::ifstream*s 的容器”。非常量指针总是可赋值的。需要注意的是,在这种情况下,您当然必须确保在销毁容器之前自己删除指针,因为容器不会为您执行此操作。

【讨论】:

  • 但是,你可以有一堆 ifstream 指针:std::stacked s;
  • 优秀!谢谢你。 - 普拉松
【解决方案2】:

由于流是不可复制的,您可以通过技术将它们放入标准容器中。

但是我们可以通过存储指向流的指针来解决这个问题。但是您不想将指向流的指针(特别是如果它们是动态分配的)存储在标准容器中。因此,我们希望寻求解决方案。

Boost 有指针容器的概念。
这允许您动态分配对象并将指针存储在指针容器中,然后指针容器获取对象的所有权并让您可以访问动态对象,就好像它是对象(而不是指针)一样。

因为指针容器拥有所有权,所以您不必担心删除对象。容器会这样做。

因为它允许以对象而不是指针的形式访问包含的对象,它允许您以更自然的方式在标准算法中使用流(与指针容器一起使用)。

【讨论】:

    【解决方案3】:

    在这里支持 Tyler(在投票 +1 之后)。

    stl 容器在您提供给它们的对象的所有位置上进行复制。如果您愿意,您可以通过为它们提供特殊对象以及精心设计的复制构造函数和带有引用计数等的解构函数来解决这个问题。

    一般来说,我觉得那样太麻烦了。根据经验,仅使用容器中的小物件。如果您想创建一堆结构或类,请改用指向它们的指针

    【讨论】:

    • 作为我的经验法则:1) 仅组成(更高级别)成员的正确实现复制的类(例如std::string,而不是char*),2)否则存储智能指针(和确保类是不可复制的)。
    • 即使你做#1,在我的(通常是实时的)工作中,复制大对象,或者任何可能涉及动态分配/释放的事情,都是一件坏事。
    • 在这种情况下,您可能会使用特殊的内存池等(因为您不能动态分配指针),这使得 C++ 的使用更加具体。对于初学者来说,避免vector&lt;string&gt; 转而使用&lt;vector&lt;string*&gt;,您真的认为这是个好建议吗? IMO,开销通常并不重要,除非在非常特定的情况下。
    猜你喜欢
    • 2021-10-27
    • 2016-12-05
    • 1970-01-01
    • 2012-01-17
    • 1970-01-01
    • 2021-12-13
    • 2013-07-03
    • 2015-04-30
    相关资源
    最近更新 更多