繁体   English   中英

受控单例变量的Ada初始化

[英]Ada initialization of controlled singleton variable

我试图用自动初始化的单例变量创建一个包。 如果单例变量不是受控类型,则编译器不会抱怨,但是当我将其设为受控类型时,我会收到警告:“无法在看到正文之前调用初始化”

后跟:“程序错误将在运行时引发。”

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

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;

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

提出的这个问题的答案是-正如编译器所说的-“不能在看到正文之前调用Initialize”。 也就是说,程序文本中调用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 )之前就详细说明程序包主体:

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;

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM