・ RAII用のクラス作れよ
・ boost/scope_exit使えよ
ということのようだ、前者はそれ用のクラス毎回作るのもなんだかなーだし、後者はちょっとぐじゃぐじゃしてて嫌だった。
頭に来たので、RAII用にshared_ptrを流用することにしたので、以下にメモっておく。
あ、c++11必須ね。
#include <iostream>
#include <string>
#include <memory>
#include <stdexcept>
using namespace std;
#define FINALLY(CLAUSE) shared_ptr<void> f_i_n_a_l_l_y(nullptr, [&](void*){CLAUSE});
class SomeResource {
public:
void open() {cout << "some resource open." << endl;}
void close() {cout << "some resource close." << endl;}
};
int main() {
try {
SomeResource res;
FINALLY(
res.close();
)
res.open();
cout << "before throw exception." << endl;
throw runtime_error("xxx error.");
cout << "end of try block." << endl;
} catch (runtime_error &e) {
cout << "Error: " << e.what() << endl;
}
cout << "out of try block." << endl;
}
実行した結果は、
some resource open. before throw exception. some resource close. Error: xxx error. out of try block.マクロ使って少し見やすくしました。
注意点は、FINALLYを解放したいリソースの宣言と例外が出る可能性のある場所の「間」に入れるところです。
こう見ると、shared_ptrのカスタムデリーターって、いろんなことに流用できそうですね。ちゃんとカウント取ってるからそこの一部のスコープだけに限らず使えるし。
後処理という発想だけでなく、なんかのトリガー的なことに使うと面白そう。

