我怎样才能在 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;