使用RefCounted在D中制作引用计数对象!(T)

Meh*_*dad 8 d reference-counting refcounting

你如何使用std.typecons.RefCounted!(T)D中的引用计数对象?

我试图std.array.Array通过查看源代码来弄清楚内部是什么,但是虽然我可以阅读源代码,但我无法确定什么是"有效负载"或者当有涉及按位结构复制的事情时它是如何工作的,以及为什么有些东西在内部和外部结构中重复.

任何人都可以提供一个示例或链接,如何使用它,比如,包装一个简单的Win32 HANDLE

谢谢!

he_*_*eat 9

免责声明:我没有测试我的说法,只是阅读文档.

有效载荷指的是存储的内容.在您的情况下,有效负载是Win32 HANDLE.由于HANDLE只是一个整数,你不想这样做:

auto refHandle = RefCounted!HANDLE(WhatGetsMeAHandle());
Run Code Online (Sandbox Code Playgroud)

因为当句柄超出范围时需要调用Windows函数.

在std.containers.Array你看到的是一个名为Payload的结构,它有一个名为_payload的字段.结构将是通过_payload访问的数据存储.这提供了稍后要使用的间接级别.

您会注意到RefCounted实际上是在Array结构上使用的.这意味着只有当引用计数为0时才会调用该结构的析构函数.因此,Payload中的~this()是您希望清理HANDLE的地方.

发生了什么:因为struct是一个值类型,每次结构超出范围时都会调用析构函数,没有一个用于Array,但是Payload包含在RefCounted中,RefCounted的析构函数也被称为Payload.并且只有当引用计数达到零时才会调用Payload本身的析构函数.

现在,RefCounted本身有引用语义,这意味着有一个数组a,你可以再分配给auto b = a; 并且所有内容都将被复制,但RefCounted 定义postblits意味着不会复制数据,但引用计数将增加.

我现在将尝试为您提供所需内容的包装大纲.它可能会帮助您可视化上面的信息,但它可能不完全正确.如果有什么需要修复,请告诉我.

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); }
}
Run Code Online (Sandbox Code Playgroud)

由于结构没有默认构造函数,因此您可能希望提供一个返回此结构的自由函数.