Ada初始化受控单例变量

时间:2015-10-25 06:18:31

标签: singleton ada static-members static-initialization

我正在尝试创建一个包含自动初始化的单例变量的包。如果单例变量不是受控类型,那么编译器不会抱怨,但是当我对其进行控制时,我会收到警告:“在看到body之前无法调用Initialize”

其次是: “程序错误将在运行时引发。”

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

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;

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

2 个答案:

答案 0 :(得分:4)

提出这个问题的答案是 - 正如编制者所说 - "在看到身体之前无法调用Initialize&#34 ;;就是这个地方 调用Initialize的程序文本必须在该位置之后 找到Initialize正文的程序文本。这是一个 (也许是历史的)对one-pass compilers的渴望的后果。

因为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):所以

The_Singleton: aliased Singleton_Type;

Initialize的隐式调用可能没有发生(哪个 会导致Program_Error有一个不同的原因,在 交易为"在详细说明之前访问"或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;

答案 1 :(得分:0)

我想到的解决方法:如果动态内存不是障碍,您可以在包的正文中分配对象,并且可以访问而不是常规实例供您的孩子查看。