2011-01-08 36 views
8

如何使用std.typecons.RefCounted!(T),以使d引用计数的对象?制作使用引用计数在d引用计数的对象!(T)

我试图找出什么std.array.Array在内部通过查看源代码,但虽然我可以读取源,但我不能确定什么是“有效载荷”或它是如何工作的涉及的按位结构复制,以及为什么有些东西在内部和外部结构中是重复的。

谁能提供一个例子或如何使用它,比方说,包装一个简单的Win32 HANDLE链接?

谢谢!

回答

9

免责声明:我没有测试过我的权利,只是读了documentation

有效载荷指的是正在存储的内容。在你的情况下,有效载荷是Win32 HANDLE。由于HANDLE只是一个整数,你不会想要做的:

auto refHandle = RefCounted!HANDLE(WhatGetsMeAHandle()); 

因为Windows功能将需要在手柄超出范围被调用。

在std.containers.Array你看到一个叫做有效载荷结构,其中有一个叫_payload场。该结构将成为通过_payload访问的数据存储。这提供了一个间接的级别以备后用。

你会发现,引用计数实际上是used on the Array structure。这意味着只有在引用计数为0时才会调用该结构的析构函数。因此,Payload中的〜this()是您希望清理HANDLE的地方。

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

现在,引用计数本身具有引用语义,这意味着具有阵列一个,则可以分配给汽车B = A;并且所有内容都将被复制,但RefCounted具有postblits defined这意味着数据不会被复制,但引用计数将会增加 。

我现在会尝试为您提供一个包装大纲。它可能会帮助你看到上面的信息,但它可能不完全正确。让我知道是否需要修复。

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); } 
} 

由于没有结构的默认构造函数,您可能想要提供一个返回此结构的免费函数。

+0

谢谢您的详细解答!你让它看起来很简单! :) – Mehrdad 2011-01-08 21:20:50