我正在尝试创建一个包含自动初始化的单例变量的包。如果单例变量不是受控类型,那么编译器不会抱怨,但是当我对其进行控制时,我会收到警告:“在看到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;
如何创建一个初始化的单例变量,并在开始创建对象实例时准备好使用?提前谢谢。
答案 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)
我想到的解决方法:如果动态内存不是障碍,您可以在包的正文中分配对象,并且可以访问而不是常规实例供您的孩子查看。