Rule of Zeroというイディオムについて説明している記事があります。
ここに抜粋があります:
class module {
public:
explicit module(std::wstring const& name)
: handle { ::LoadLibrary(name.c_str()), &::FreeLibrary } {}
// other module related functions go here
private:
using module_handle = std::unique_ptr<void, decltype(&::FreeLibrary)>;
module_handle handle;
};
RAII 機能を再利用unique_ptr
するため、困難で冗長な Rule of Five ラッパーの実装を気にする必要はありません。
このように提示された(ハンドルベースのリソースをunique_ptr
そのように管理する)と、私にとってはハックのように見えますが、解決しようとしているものの最善の解決策ではありません。あまりにも多くの仮定が暗黙のうちに仮定されています:
#define
(またはtypedef
)HANDLE
が構築されている基本型をピアリングして使用することができます。私にとって、これは隠された知識であるべきであり、解決策はインターフェースが利用可能にするもののみに基づいている必要があります:HANDLE
.- ハンドルは何でもかまいません。ポインター型である必要はありません。
私はこのイディオムを使いたいと思っていますが、私が遭遇する多くの状況では不十分です。
このハンドルに焦点を当てた RAII ラッパーは既に作成されており、クールなライブラリで使用できますか? 誰もがそのようなツールを使用していますが、私は気づいていませんか? (1つだけでなく、さまざまな種類の所有権のためにそのようなツールがあると便利だと思います)
編集1
これは、プラットフォーム固有のリソース ハンドルに関するものではありません。たとえば、glGenLists
ある種のハンドルを返します。これは であり、これGLuint
を呼び出す必要がありますglDeleteLists
。既に述べたように、リソース ハンドルはポインター型である必要はなく、この仮定は仮定されるべきではありません。
編集2
前者のサンプルのルール オブ ゼロは、既存のツールを使用することにより、unique_ptr
ハンドル管理の優れたショートカットとして表示されます。それが必要とする余分な仮定により、それは不十分になります。正しい仮定は、ハンドルがあり、ハンドルによって指定されたリソースを破棄するリソース破棄関数があることです。ハンドルが a 、 a 、何であれ、それは問題ではなく、さらに悪いことに、内部型をピアリングする必要さえありません。ハンドルを RAII のように管理する目的で、イディオムがそれで良いと言っていて、そのような状況では適用できない場合、それは良くないと感じます。void *
GLuint
HANDLE
編集3
たとえば、新しいサード パーティの C ライブラリの使用を担当しているとします。と が含まれていFooHandle create_foo()
ますvoid destroy_foo(FooHandle)
。「ゼロの法則を使って FooHandle を使おう」と。わかりました、あなたはあなたが自問するものにa unique_ptr
、 aを使って行きますか? toの公開されていない基本型を使用するにunique_ptr
はFooHandle
、ポインターですか? それは? なので、そのまま使用できますか、それとも @NicolBolas が彼の回答で行ったようなことを (再) する方がよいでしょうか。私にとっては、このような些細な状況であっても、リソース ハンドルを管理するのに理想的ではないことがすでに明らかになっているように思えます。unique_ptr
FooHandle
int
typedef
unique_ptr
免責事項:
私は自分自身を再定式化し、よりよく表現しようとしました:
編集4
私は探していたものを見つけました。再定式化された質問の答えとしてそれを入れました: https://stackoverflow.com/a/14902921。