How to handle file destructor throwing an exception?

It is important to detect an error when closing the file that you wrote to, because the last part of your data could be cleared during closing, and if it is lost, your last record was effectively unsuccessful, and someone should know about it, Destructor for A file object is a great place to close automatically, but people say they don’t throw exceptions from destructors, so if closing fails, then how do you know about it?

I heard that people recommend manually accessing the close () method. This sounds good, except what happens if the close () methods for multiple files do not work in this situation:

    MyFile x(0), y(1), z(2);
    x.close();
    y.close();
    z.close();

?

Well, it looks like if the close () method for "x" throws an exception, you did your best to defend the rule to avoid throwing exceptions in the "x" destructor, except that you intentionally made early calls to the close () "y" methods and "z" will not be executed until their destructors. So, then, when the close () method "y" is called in the destructor "y" or the close () method "z" is called in the destructor "z", and if they make exceptions, then you are "screwed".

Is there any reasonable way not to get into such a situation?

+3
source share
7 answers

Yes, catch the exception thrown with the destructor closing.

, ++ . .

, , . , .

+5

: 17.3 , ?

Edit:

, , close() 'x' , , 'x', , close() 'y' 'z' .

. Dtors y z , , try-catch, MyFile ... z.close(). a close dtor. Dtor x - catch .

, dtor- ( , S x):

#include <iostream>

using namespace std;

struct s {
 s(int i = 0) : m_i( i ) { cout << __func__ << endl; }
 ~s() { if (m_i == 0) except(); cout << __func__ << endl; }
 void except() { throw 42; }
 int m_i;
};

int main() {
  try
  {
      s y(2), z(3);
      /* s x */
      y.except();
  }
  catch (...) { cout << "exception\n"; }

  cout << "stack unwound\n";
}
+2

- :

, , :

1: .

2. - (, ) () , .

1 2 .

2 :

WrapFileX.close();
WrapFileY.close();
WrapFileZ.close();

if(WrapFileX.hasError || WrapFileY.hasError || WrapfileZ.hasError)
{   //log
    exit(1)
}
+1

, - . , - . , ; . , , .

close() , .

+1

, , :

, ( ). ( - ), .

{
    std::fstream   X("Plop_X");
    std::fstream   Y("Plop_Y");
    std::fstream   Z("Plop_Z");

    // Do work

    try
    {
         X.close();
    }
    catch(Plop const& e)
    {
         // Fix the exception
         // Then make sure X closes correctly.

         // If we can't fix the problem
         // rethrow
         if (badJuJu)
         {    throw;
         }
    }
    // Don't care about Y/Z let the destructor close them and discard the exception.
}
+1
try {
x.close();
y.close();
z.close();
}
catch {
//do what ever you need to do here, then close() what' you'll need to close here
}

, , , , , , .

0

-, MyFile ( "" - "", , , ):

~MyFile() {
    try {
        close();
    } catch(...) {}
    // other cleanup
}

, . , . , . , , , , , :

MyFile x(0), y(1), z(2);
try {
    x.close();
    y.close();
    z.close();
} catch(...) {
    std::cerr << "something failed to close\n";
}

, , , :

MyFile x(0), y(1), z(2);
try {
    x.close();
} catch(...) {
    std::cerr << "x failed to close\n";
}
try {
    y.close();
} catch(...) {
    std::cerr << "y failed to close\n";
}
try {
    z.close();
} catch(...) {
    std::cerr << "z failed to close\n";
}

, . , , close , catch, (...).

, close() , , .

0
source

Source: https://habr.com/ru/post/1730883/


All Articles