我怎样才能在 Ada 中做一个 unchecked_deallocation of abstract 类?
How can I do an unchecked_deallocation of abstract classes in Ada?
我对 Ada 非常了解,但我仍然在一般的 OO 中挣扎,特别是在 Ada 中。因此,很可能我只是漏掉了一点。
考虑像树这样的数据结构。存储在树中的对象是抽象类型的。我想要完全控制释放(使用 Ada.Finalization),因为我正在使用安全指针实现数据结构。这意味着在释放树时,当仍然有对它的引用时,不得释放子树。
在这种情况下,需要释放数据结构中引用的具体对象。在我看来,这需要一个抽象unchecked_deallocation。有没有简单的方法可以做到这一点?我还考虑过声明一个抽象 Free 子例程,它必须由抽象类型的实例实现。不成功。
In 还没有检查标准库是否有合适的数据结构。目前我只是对问题本身感到好奇。
这在一个下雨的星期天早上很有趣!
基本技巧是对要释放的类型使用 Foo’Class
,对访问类型使用 access Foo’Class
。
generic
type T is abstract tagged private;
type T_Access is access T'CLass;
package Abstract_Deallocation is
type Holder is private;
function Is_Empty (H : Holder) return Boolean;
procedure Add (To : in out Holder; Item : T_Access);
procedure Release (H : in out Holder)
with Post => Is_Empty (H);
private
type Holder is new T_Access;
function Is_Empty (H : Holder) return Boolean
is (H = null);
end Abstract_Deallocation;
with Ada.Unchecked_Deallocation;
package body Abstract_Deallocation is
procedure Free is new Ada.Unchecked_Deallocation
(T'Class, T_Access);
procedure Add (To : in out Holder; Item : T_Access) is
begin
To := Holder (Item);
end Add;
procedure Release (H : in out Holder) is
begin
Free (T_Access (H));
end Release;
end Abstract_Deallocation;
with Abstract_Deallocation;
procedure Abstract_Deallocation_Test is
type Actual_T is abstract tagged null record;
type Actual_T_Access is access all Actual_T'Class;
package Demo is new Abstract_Deallocation
(T => Actual_T,
T_Access => Actual_T_Access);
type Concrete_T is new Actual_T with null record;
Holder : Demo.Holder;
begin
Demo.Add (Holder, new Concrete_T);
Demo.Release (Holder);
end Abstract_Deallocation_Test;
我对 Ada 非常了解,但我仍然在一般的 OO 中挣扎,特别是在 Ada 中。因此,很可能我只是漏掉了一点。
考虑像树这样的数据结构。存储在树中的对象是抽象类型的。我想要完全控制释放(使用 Ada.Finalization),因为我正在使用安全指针实现数据结构。这意味着在释放树时,当仍然有对它的引用时,不得释放子树。
在这种情况下,需要释放数据结构中引用的具体对象。在我看来,这需要一个抽象unchecked_deallocation。有没有简单的方法可以做到这一点?我还考虑过声明一个抽象 Free 子例程,它必须由抽象类型的实例实现。不成功。
In 还没有检查标准库是否有合适的数据结构。目前我只是对问题本身感到好奇。
这在一个下雨的星期天早上很有趣!
基本技巧是对要释放的类型使用 Foo’Class
,对访问类型使用 access Foo’Class
。
generic
type T is abstract tagged private;
type T_Access is access T'CLass;
package Abstract_Deallocation is
type Holder is private;
function Is_Empty (H : Holder) return Boolean;
procedure Add (To : in out Holder; Item : T_Access);
procedure Release (H : in out Holder)
with Post => Is_Empty (H);
private
type Holder is new T_Access;
function Is_Empty (H : Holder) return Boolean
is (H = null);
end Abstract_Deallocation;
with Ada.Unchecked_Deallocation;
package body Abstract_Deallocation is
procedure Free is new Ada.Unchecked_Deallocation
(T'Class, T_Access);
procedure Add (To : in out Holder; Item : T_Access) is
begin
To := Holder (Item);
end Add;
procedure Release (H : in out Holder) is
begin
Free (T_Access (H));
end Release;
end Abstract_Deallocation;
with Abstract_Deallocation;
procedure Abstract_Deallocation_Test is
type Actual_T is abstract tagged null record;
type Actual_T_Access is access all Actual_T'Class;
package Demo is new Abstract_Deallocation
(T => Actual_T,
T_Access => Actual_T_Access);
type Concrete_T is new Actual_T with null record;
Holder : Demo.Holder;
begin
Demo.Add (Holder, new Concrete_T);
Demo.Release (Holder);
end Abstract_Deallocation_Test;