【问题标题】:‘std::ostream’ has no member named ‘close’“std::ostream”没有名为“close”的成员
【发布时间】:2015-05-28 01:37:13
【问题描述】:

std::ostream 没有成员函数close()。什么类型的流不应该被允许关闭?

例如,也许我想关闭 std::cout 以防止任何进一步的写入。

std::cout.close(); // ‘std::ostream’ has no member named ‘close’

如果我使用的是 C 库,我可以使用以下命令关闭 stdout

fclose(stdout); // no problem

那么从std::ostream 中省略close() 成员的想法是什么?


相关:

【问题讨论】:

  • ostream 是一个抽象,它没有 closeopen 因为并非所有流(或者更确切地说是它们的底层缓冲区)都可以关闭或打开,如您所见。对于它的价值,fclose(stdout); 仍然可以在 C++ 中工作,因为coutstdout 明确关联。
  • 关闭 ostream 非常有意义——这意味着不应再向其发送输出,任何尝试这样做都应在流上设置错误标志...
  • 有趣:ofstream 的析构函数被描述为'隐式声明',同时被显式记录为关闭文件。我不知道这将如何工作,除非(它的父级)ostream 有一个虚拟的close(可能是间接的)。

标签: c++ iostream


【解决方案1】:

close() 函数作为std::ostream 的成员是没有意义的。第一个例子是std::ostringstream 继承自std::ostream。关闭字符串有意义吗? std::ostream 的唯一成员是输入/输出的全局对象。

文件流具有close() 函数,因为能够将资源释放到环境中很重要。但是,由于从该基类继承的其他类不需要此函数,因此将其作为std::ostream 的一部分是没有意义的,这就是它仅用于文件流的原因。

【讨论】:

  • 有道理,只是我不明白为什么 std::ostringstream 不应该被关闭。不像open(),它显然与特定的子类相关联,close() 是一个非常通用的操作,它可能对任何类型的流都有意义——它只是意味着你已经完成了写入并且任何未来的写入操作都应该返回一个错误。从概念上讲,它至少与flush() 一样通用,ostream 确实提供了它。但你是对的——close() 对于某些类型的流比其他类型的流更必要
  • 如果你完成了对字符串的写入,你应该只从项目中查询字符串。我承认我对stirngstreams 的大部分使用都是为了这样的事情:std::string intToStr(int i){ std::ostringstream temp; return (temp << i), temp.str();} 当流本身关闭时,封闭范围清楚地表明了这一点。刷新是一种告诉底层流您应该清空当前写入缓冲区并写入实际流的方法,因此它是不同的。在我看来,close() 本身即使对于文件也不是必需的。
  • ostream的(普通)构造函数是从什么时候被删除的?
  • 我忘记了导入部分。它是复制构造函数而不是构造函数。
  • @meneldal 虽然对于简单的intToStr(),您可以只使用std::to_string()(C++11 起)。
【解决方案2】:

这是一种伪装的方法:

void ostream_fake_close( std::ostream & os )
   {
   os.flush();
   static std::stringstream closed_flag;
   cerr<<(os.rdbuf()==closed_flag.rdbuf()?"closed":"open")<<"\n";
   os.rdbuf(closed_flag.rdbuf());
   cerr<<(os.rdbuf()==closed_flag.rdbuf()?"closed":"open")<<"\n";
   }

未来对流的写入将被重定向到closed_flag 缓冲区。您可以通过定期resetting it 来限制缓冲区的大小:

closed_flag.str("");

对象被销毁时会自动发出真正的关闭。

【讨论】:

    【解决方案3】:

    除了梅内尔达尔的出色回答。

    如果您以后需要访问某些类型的资源,不释放资源仍然可能会导致问题。 如果出于某种原因您不想使用ofstream(它有一个close 方法),请坚持使用ostream。你可以让它超出范围。

    例子:

    std::string FilePath = "C:/Test/MyFile.ext";
    
    {  // <== Note the start of scope.
    
            // Writing a file using ostream as by example given by cplusplus.com reference.
            std::filebuf outfb;
            outfb.open(FilePath, std::ios::out);
            std::ostream os(&outfb);
    
            /* Do your stuf using 'os' here. */
    
    }  // <== Note the end of scope.
    
    /* Here, the resource is freed as if you would have called close. */
    /* Rest of code... */
    

    更新: 但是,现在我想起来了,在这种情况下,std::filebuf 提供了close 方法,它也可以解决您的问题。

    【讨论】:

      猜你喜欢
      • 2015-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 2012-12-20
      • 2014-06-20
      • 1970-01-01
      相关资源
      最近更新 更多