你如何std.typecons.RefCounted!(T)
在 D 中创建一个引用计数的对象?
我试图通过查看源代码来弄清楚std.array.Array
内部是做什么的,但是虽然我可以阅读源代码,但我只是无法弄清楚“有效负载”是什么,或者当涉及到按位结构复制之类的事情时它是如何工作的,以及为什么有些东西在内部和外部结构中是重复的。
谁能提供一个示例或链接来说明如何使用它来包装一个简单的 Win32 HANDLE
?
谢谢!
你如何std.typecons.RefCounted!(T)
在 D 中创建一个引用计数的对象?
我试图通过查看源代码来弄清楚std.array.Array
内部是做什么的,但是虽然我可以阅读源代码,但我只是无法弄清楚“有效负载”是什么,或者当涉及到按位结构复制之类的事情时它是如何工作的,以及为什么有些东西在内部和外部结构中是重复的。
谁能提供一个示例或链接来说明如何使用它来包装一个简单的 Win32 HANDLE
?
谢谢!
免责声明:我没有测试我的声明,只是阅读文档。
有效负载是指正在存储的内容。在您的情况下,有效负载是 Win32 HANDLE。由于 HANDLE 只是一个整数,你不想这样做:
auto refHandle = RefCounted!HANDLE(WhatGetsMeAHandle());
因为当句柄超出范围时需要调用 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); }
}
由于结构没有默认构造函数,您可能希望提供一个返回此结构的免费函数。