多くの場合、C++ プログラムは、リソースの割り当てと解放のためのフリー関数を提供する C ライブラリを処理する必要があります。この例を簡単にするために、 と のような 2 つの C 関数について考えてみget_resource()
ますfree_resource()
。
オブジェクトがその寿命のある時点でリソースを取得し、オブジェクトが破棄されるか、構築中のエラーのために完全に構築されていない場合、自動的に解放することを検討してください。
その自動化を得るための理想的/短い/簡単なイディオムは何ですか? アイデアは次のとおりですが、オブジェクトが適切にデフォルトで移動可能になりません。デストラクタ内からメモリを解放したり、コンストラクタでエラーをチェックしてロールバックを実行したりすることを意味しない、より良いものはありますか?
struct Object {
void* my_get_resource() { // might be called from the constructor or any other point
return get_resource();
}
Object() : up(&resource, &del) {
resource = my_get_resource();
/* init all the stuff, but this init might fail at _many_ points */
}
//~Object() { if (resource) free_resource(resource); } // I don't like: collides with del and is not called if my_get_resource() is called from the constructor and the init process fails for some reasons
private:
void *resource = nullptr;
static void del(void ** ) noexcept {
if (*resource) { free_resource(resource); }
}
unique_ptr < void*, decltype(&del) > up; // RAII: almost good, sadly that makes Object not moveable properly without redefining the move constructor properly
};