【问题标题】:What is std::ios::exceptions expected behavior in destructor?析构函数中的 std::ios::exceptions 预期行为是什么?
【发布时间】:2014-05-20 13:31:08
【问题描述】:

考虑一下这个sn-p:

// Case 1: Explicitly calling close() does throw, as expected.
{
    std::ifstream f;
    f.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
    f.close();  // This will throw std::ifstream::failure, as close() on unopened file sets the failbit
}

// Case 2: close() will be called by destructor of object 'g', but does not throw.
{
    std::ifstream g;
    g.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
} // Does not throw, even though "g's" destructor will call close() method

现在我明白析构函数永远不应该在 C++ 中泄漏异常(这可能是案例 2 中观察到的行为的原因)。我的问题是:C++ 标准是否保证上述观察到的行为如此,或者它只是一个人工制品(如果是的话,C++03 和 C++11 在这方面有什么区别吗?任何相关的引用C++ 标准会很有帮助)。

另外,这种不抛出内部析构函数的特殊情况通常是如何实现的,析构函数代码是否只是捕获 close() 抛出的异常,并忽略它们?有人可以指出我在任何主要编译器源代码中的实现。

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    virtual ~basic_filebuf();

    27.9.1.2/5 效果:销毁类对象 basic_filebuf<charT,traits>。致电close()。如果发生异常 在对象的销毁期间,包括对 close() 的调用, 异常被捕获但不被重新抛出(参见 17.6.5.12)。

    强调我的。

    【讨论】:

    • 谢谢!我想知道 g++ 是如何实现它的,因为查看头文件 fstream (g++ 4.6) 的源代码,这是我所看到的:virtual ~basic_filebuf() { this->close(); } 。在那里看不到任何 try { } catch { } 逻辑:-/ -有什么线索吗?
    • 参考(适用于 gcc 4.9):gcc.gnu.org/onlinedocs/gcc-4.9.0/libstdc++/api/…
    • 请注意exceptions() 方法位于std::ios,而不是streambuffilebuf::close() 没有设置 failbit (它没有可以设置它的成员),并且(通常)不会抛出异常。当没有打开的文件时,它什么也不做并返回NULL。反过来,fstream::close 调用filebuf::close,当后者返回NULL 时,设置failbit(可能会抛出)。但是,fstream 的析构函数不会调用fstream::close()(它通过filebuf 析构函数间接调用filebuf::close)。
    【解决方案2】:

    您观察到的行为是标准的。 basic_ifstream 类包含一个 basic_filebuf 对象(§27.9.1.6)。 basic_filebuf 对象的析构函数调用basic_filebuf::close,但会抑制抛出的任何异常。

    引用§27.9.1.2/5 [filebuf.cons](强调添加)

    virtual ~basic_filebuf();
    效果: 销毁类的对象 basic_filebuf<charT,traits>。致电close()。如果发生异常 在对象销毁期间,包括对close()的调用, 异常被捕获但不被重新抛出(参见 17.6.5.12)。

    【讨论】:

      猜你喜欢
      • 2017-08-21
      • 2016-07-25
      • 2021-05-09
      • 2018-10-06
      • 2014-01-02
      • 2019-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多