shared_ptr でハンドラリソース管理の話とか

2011/12/02

shared_ptr の deleter に CloseHandle なんかを指定してハンドラリソースを管理しようとかいった話があります。で,そのままこの方法を使うと,いろいろリークしてしまうので,某所では指定の仕方をいろいろと工夫して悩んでいる様子。

しかしこれ,自分がアホだからかよく分からなかったんだけれども,pimpl でくるんでしまえばいいだけの話なんじゃないだろうか。これなら,ポインタ参照先(pimpl)が破棄されるタイミングでハンドラも解放されて,実質的にハンドラとポインタは同じ扱いになる。pimpl いやーん,とゆ方には無理な話なんだけど。

class file {
  class impl;
public:
  shared_ptr<impl> pimpl_;
};

class file::impl {
  ~file::impl() {
    if (is_valid(handle_)) {
      ::CloseHandle(handle_);
    }
  }
private:
  HANDLE handle_;
};

ハンドラを共通にして一部に亜種を作りたいなら,impl 型を traits 付きのテンプレートにすればいい。

template<typename HandlerTraits_>
class impl { ... };

ま,言いたいことはそゆことではなくて,なんつか,Windows API の HANDLE 型や HMODULE 型ってのは,それ自体「システム側の都合に合わせて」ポリモーフィックにできていることを理解しておかないと,抽象化してもあまり意味がないんでねいかと。HANDLE 型にはコンテキストがあるわけで,つまり,CreateFile の文脈なのか,Mutex の文脈なのかでやってることがまるで変わってしまう。この場合,HANDLE 型は同じに見えても別のものなわけで,外部から抽象化しようとすると無理が出てしまう。

なんでも共通化しようと思って,却って分かりづらくなる好例だなあ,とかつらつら。

Site Navigation
SNS Accounts (@aian)

普段はここら辺に住んでいます.