8

std.typecons.RefCounted!(T)Dで参照カウントオブジェクトを作成するためにどのように使用しますか?

ソースを見て内部で何が行われるかを理解しようとしましたstd.array.Arrayが、ソースを読み取ることはできますが、ビット単位の構造体コピーなどが含まれる場合、「ペイロード」とは何か、またはすべてがどのように機能するかを理解できません。また、内部構造と外部構造でいくつかのものが重複している理由も同様です。

誰かがそれを使用して、たとえば単純なWin32をラップする方法の例またはリンクを提供できHANDLEますか?

ありがとう!

4

1 に答える 1

9

免責事項: 私は自分の主張をテストしていません。ドキュメントを読んでください。

ペイロードとは、格納されているものを指します。あなたの場合、ペイロードは 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); }
}

構造体にはデフォルトのコンストラクターがないため、おそらくこの構造体を返すフリー関数を提供したいと思うでしょう。

于 2011-01-08T17:11:53.723 に答える