免責事項: 私は自分の主張をテストしていません。ドキュメントを読んでください。
ペイロードとは、格納されているものを指します。あなたの場合、ペイロードは Win32 HANDLE です。HANDLE は単なる整数なので、やりたくないでしょう:
auto refHandle = RefCounted!HANDLE(WhatGetsMeAHandle());
ハンドルがスコープ外になると、Windows 関数を呼び出す必要があるためです。
std.containers.Array には、_payload というフィールドを持つ Payload という構造体がありました。構造体は、_payload を介してアクセスされるデータのストレージになります。これにより、後で使用する間接的なレベルが提供されます。
RefCounted が実際には Array 構造体で使用されていることがわかります。これは、その構造体のデストラクタが参照カウントが 0 の場合にのみ呼び出されることを意味します。したがって、ペイロード内の ~this() は、ハンドルをクリーンアップする必要がある場所です。
何が起こっているか: 構造体は値型であるため、構造体がスコープ外になるたびにデストラクタが呼び出され、Array 用のデストラクタはありませんが、Payload は RefCounted にラップされ、RefCounted!Payload のデストラクタも呼び出されます。そして、参照カウントがゼロに達したときにのみ、ペイロード自体のデストラクタが呼び出されます。
現在、RefCounted 自体に参照セマンティクスがあります。これは、配列 a を使用して、auto b = a; に割り当てることができることを意味します。すべてがコピーされますが、RefCounted にはポストブリットが定義されているため、データはコピーされませんが、参照カウントはインクリメントされます。
私は今、あなたが望むもののためのラッパーのアウトラインを提供しようとします. 上記の情報を視覚化するのに役立つかもしれませんが、完全に正しいとは限りません。何か修正が必要な場合はお知らせください。
struct MyWinWrapper {
struct Payload {
HANDLE _payload;
this(HANDLE h) { _payload = h; }
~this() { freeHandleHere(_payload); }
// Should never perform these operations
this(this) { assert(false); }
void opAssign(MyWinWrapper.Payload rhs) { assert(false); }
}
private alias RefCounted!(Payload, RefCountedAutoInitialize.no) Data;
private Data _data;
this(HANDLE h) { _data = Data(h); }
}
構造体にはデフォルトのコンストラクターがないため、おそらくこの構造体を返すフリー関数を提供したいと思うでしょう。