如何在 Ada 中对抽象类进行 unchecked_deallocation?

Har*_*aun 4 abstract-class ada dynamic-memory-allocation

我非常了解 Ada,但总体而言,我仍然在为面向对象而苦苦挣扎,尤其是在 Ada 中。因此,很可能我只是遗漏了一点。

考虑像树这样的数据结构。存储在树中的对象是抽象类型的。我想完全控制解除分配(使用 Ada.Finalization),因为我正在使用安全指针实现数据结构。这意味着在释放树时,子树在仍然存在引用时不能被释放。

在这种情况下,需要释放数据结构中引用的具体对象。在我看来,这需要一个抽象的 unchecked_deallocation。有没有一种简单的方法可以做到这一点?我还考虑声明一个抽象的Free子例程,该子例程必须由抽象类型的实例实现。不成功。

In 还没有检查标准库以获得合适的数据结构。目前我只是对问题本身感到好奇。

Sim*_*ght 6

这在一个下雨的星期天早上很有趣!

基本技巧是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;
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)