受控单例变量的ada初始化

Ada initialization of controlled singleton variable

我正在尝试创建一个包含自动初始化的单例变量的程序包。如果单例变量不是受控类型,那么编译器不会报错,但是当我让它受控时,我会收到警告:"cannot call Initialize before body seen"

其次是: "Program error will be raised at run time."

因此,我认为编译器希望对子对象隐藏单例变量,但这不是我想要的。这是我的代码:

with Ada.Finalization;

package static_member is
   type singleton_type is tagged limited private;

private
   type singleton_type is new Ada.Finalization.Limited_Controlled with record
      data_to_init: Natural;
   end record;

   overriding procedure Initialize(data: in out singleton_type);
   overriding procedure Finalize(data: in out singleton_type);

   --This is where I get the warnings.
   --I want singleton to be visible to child objects.
   singleton: singleton_type;
end static_member;

那么包体就是:

package body static_member is
   overriding procedure Initialize(data: in out singleton_type) is
   begin
      data.data_to_init := 0;
   end Initialize;

   overriding procedure Finalize(data: in out singleton_type) is null;
end static_member;

我如何创建一个已初始化并在对象实例开始创建时准备好使用的单例变量?提前致谢。

想到的解决方法:如果动态内存没有障碍,您可以在包的主体中分配 object 并拥有一个访问权限,而不是 children 的常规实例看

这个问题的答案是——正如编译器所说—— "cannot call Initialize before body seen";也就是说,在的地方 调用 Initialize 的程序文本必须在中的位置之后 找到 Initialize 正文的程序文本。这是一个 (也许是历史的)渴望一次通过的结果 编译器.

因为Initialize的正文必须出现在 包(除非它为 null,这在 Ada 2012 中是合法的),这意味着 singleton 只能在包体中声明 ( 之后 Initialize 的正文,当然)。

这意味着您需要提供访问子程序供 子包:可能

with Ada.Finalization;
package Static_Member with Elaborate_Body is
   type Singleton_Type is tagged limited private;
   function Singleton return access Singleton_Type;
private
   type Singleton_Type is new Ada.Finalization.Limited_Controlled with record
      Data_To_Init: Natural;
   end record;

   overriding procedure Initialize (Data: in out Singleton_Type);
   overriding procedure Finalize (Data: in out Singleton_Type);
end Static_Member;

package body Static_Member is
   overriding procedure Initialize (Data: in out Singleton_Type) is
   begin
      Data.Data_To_Init := 0;
   end Initialize;

   overriding procedure Finalize (Data: in out Singleton_Type) is null;

   The_Singleton: aliased Singleton_Type;

   function Singleton return access Singleton_Type is (The_Singleton'Access);
end Static_Member;

Elaborate_Body 的原因是,没有它,编译器 不必在其他使用之前详细说明包体, 调用包子程序的包(例如Singleton):so

The_Singleton: aliased Singleton_Type;

Initialize 的隐式调用可能不会发生(这 将导致 Program_Error 具有不同的原因,在 交易为 "access before elaboration" 或 ABE)。


也就是说,还有其他方法可以避免使用 Ada.Finalization。您的示例代码没有显示任何特定的 使用它的理由,而且确实没有必要覆盖 Finalize (除非你想在程序关闭时发生什么?)

一种可能性(对于简单的情况)是声明 Singleton_Type 初始化:

type Singleton_Type is record
   Data_To_Init : Natural := 0;
end record;

另一种方法是在包体中进行初始化:

package Static_Member with Elaborate_Body is
   type Singleton_Type is limited private;
   function Singleton return access Singleton_Type;
private
   type Singleton_Type is limited record
      Data_To_Init : Natural;
   end record;
end Static_Member;

package body Static_Member is
   The_Singleton: aliased Singleton_Type;

   function Singleton return access Singleton_Type is (The_Singleton'Access);
begin
   The_Singleton.Data_To_Init := 0;
end Static_Member;