Ada中的构造函数 我试图实现一个构造函数,它在艾达2005中使用java或C++。
我有一个Java类:Ada中的构造函数 我试图实现一个构造函数,它在艾达2005中使用java或C++。,java,ada,Java,Ada,我有一个Java类: public class MyClass { private static int intTest = 0; private float floatTest = 0.0f; private float floatTest2 = 0.0f; public MyClass(float f_test, float f_test1) { MyClass.intTest++; this.floatTest = f
public class MyClass {
private static int intTest = 0;
private float floatTest = 0.0f;
private float floatTest2 = 0.0f;
public MyClass(float f_test, float f_test1) {
MyClass.intTest++;
this.floatTest = f_test;
this.floatTest2 = f_test1;
}
}
现在我正试图在ADA2005中实现这一点。这是我做的,但我犯了一个错误
with Ada.Finalization; use Ada.Finalization;
package MyClasses is
type MyClass (f_test, f_test1 : float)
is new Controlled with private;
type MyClass is access all MyClass'Class;
private
intTest : Integer := 0;
type MyClass( f_test, f_test1: float )
is new Controlled with
record
floatTest : float := f_test;
floatTest2 : float := f_test1;
end record;
overriding procedure Initialize (This : in out MyClass);
end MyClass;
with Ada.Text_IO;
use Ada.Text_IO;
package body MyClasses is
procedure Initialize( This : in out MyClass ) is
begin
intTest := intTest + 1;
end Initialize;
end MyClass;
在这一行,我得到了错误“鉴别器必须具有离散或访问类型”
如何像在java类中一样实现构造函数?Float不是离散类型,并且“鉴别器必须具有离散或访问类型”。艾达没有C++语言启发的语言类中的构造函数。试图改变歧视的用途就像试图在墙上钉一颗螺丝钉。如果它真的起作用的话,结果也不会很好 相反,您应该有一个creator函数来返回初始化的对象:
type MyClass is new Controlled with private;
function Create(f_test, f_test1 : float) return MyClass;
其他需要注意的事项:
- 您的访问类型MyClass与记录类型具有相同的名称。那不行
- 在Java示例中,您将intTest声明为
,但在Ada包的private部分中声明了它。这相当于受保护的,因为子包可以访问它。相反,在包体中声明它,这是真正等价于private static
私有静态
package My_Class is
type Instance is tagged private;
function Create (F_Test, F_Test_1 : Float) return Instance;
private
type Instance is tagged
record
Float_Test, Float_Test_2 : Float := 0.0;
end record;
end My_Class;
package body My_Class is
Constructed_Objects : Natural := 0;
function Create (F_Test, F_Test_1 : Float) return Instance is
begin
Constructed_Objects := Constructed_Objects + 1;
return (Float_Test => F_Test,
Float_Test_2 => F_Test_1);
end Create;
end My_Class;
我忽略了控制标记类型,因为我看不出这样做的意义
Ada不允许将公开可访问类型的完整声明推迟到包规范的私有部分。包规范的私有部分对包的子级可见(与派生类/标记类型不同),这意味着Ada中的“私有”属性在某种程度上类似于Java中的“受保护”属性。您可以使用通用包作为伪对象的形式,也可以使用Ada控制的记录。泛型包的优点是能够像模板一样将类型作为约束(数组、类型、非歧视),但是ada控制的记录更简单,更易于使用,但仅限于离散类型作为参数(这就是您所做的)。我在为Doom3创建任务安全控制台变量时使用了类似的策略
with Ada.Finalization; use Ada.Finalization;
with Ada.Text_IO; use Ada.Text_IO;
generic
F_Test_1 : Float;
F_Test_2 : Float := 2.0;
package Pretend_Class is
procedure Set_Total(Amount : Integer);
function Get_Total return Integer;
private
Total : Integer := 0; -- Total : Integer := Integer(F_Test_1 + F_Test_2) + 1;
-- Could just do this and ignore the executable section
-- and the controller object, but you may run into an
-- elaboration check failure if a function is called
-- in the assignment that was a member function of
-- the Pretend_Class package (e.g.
-- Total : Integer := Integer(F_Test_1 + F_Test_2) + 1 + Get_Total; -- Error!
type Record_Controller is new Ada.Finalization.Controlled with null record;
overriding procedure Initialize (Controller : in out Record_Controller);
overriding procedure Finalize (Controller : in out Record_Controller);
Controller : Record_Controller;
end Pretend_Class;
package body Pretend_Class is
procedure Set_Total(Amount : Integer) is
begin
Put_Line(" Total is now" Integer'image(Total));
Total := Amount;
end Set_Total;
function Get_Total return Integer is
begin
return Total;
end Get_Total;
procedure Initialize(Controller : in out Record_Controller) is
begin
Total := Integer(F_Test_1 + F_Test_2);
Total := Total + 1;
end Initialize;
procedure Finalize(Controller : in out Record_Controller) is
begin
Total := 0;
end Finalize;
begin
null; -- Total := Integer(F_Test_1 + F_Test_2) + 1 + Get_Total; -- Works here!
-- You can also just initialize in the executable section
-- and remove the controller object but you lose the ability
-- to finalize
end Pretend_Class;
with Pretend_Class;
procedure Test is
package My_Pretend_Class is new Pretend_Class(F_Test_1 => 3.0);
begin
My_Pretend_Class.Set_Total(Amount => 2);
end Test;
从一个角度来看,对象工厂模式是创建对象的自然Ada-2005方法。我知道每个返回标记类型的函数都可以是构造函数。但是为了创建一个对象,我必须执行create函数。正如这里提到的,我希望有一个自动构造函数,这样我就可以创建一个P:=newmyclass(20.0,10.0)的对象。这个参数不可能吗?@user1058712:您可以执行
P:=newmyclass'(创建(20.0,10.0))代码>,你的私有属性是对的。但是我认为Float_测试和Float_测试_2也应该在包体中吗?这取决于您的需求。Ada不仅仅是具有不同语法的Java。这是一种不同的语言。仅仅因为你通常用一种语言以特定的方式做一些事情,所以用另一种语言100%地匹配它通常不是一个好主意。
with Ada.Finalization; use Ada.Finalization;
with Ada.Text_IO; use Ada.Text_IO;
generic
F_Test_1 : Float;
F_Test_2 : Float := 2.0;
package Pretend_Class is
procedure Set_Total(Amount : Integer);
function Get_Total return Integer;
private
Total : Integer := 0; -- Total : Integer := Integer(F_Test_1 + F_Test_2) + 1;
-- Could just do this and ignore the executable section
-- and the controller object, but you may run into an
-- elaboration check failure if a function is called
-- in the assignment that was a member function of
-- the Pretend_Class package (e.g.
-- Total : Integer := Integer(F_Test_1 + F_Test_2) + 1 + Get_Total; -- Error!
type Record_Controller is new Ada.Finalization.Controlled with null record;
overriding procedure Initialize (Controller : in out Record_Controller);
overriding procedure Finalize (Controller : in out Record_Controller);
Controller : Record_Controller;
end Pretend_Class;
package body Pretend_Class is
procedure Set_Total(Amount : Integer) is
begin
Put_Line(" Total is now" Integer'image(Total));
Total := Amount;
end Set_Total;
function Get_Total return Integer is
begin
return Total;
end Get_Total;
procedure Initialize(Controller : in out Record_Controller) is
begin
Total := Integer(F_Test_1 + F_Test_2);
Total := Total + 1;
end Initialize;
procedure Finalize(Controller : in out Record_Controller) is
begin
Total := 0;
end Finalize;
begin
null; -- Total := Integer(F_Test_1 + F_Test_2) + 1 + Get_Total; -- Works here!
-- You can also just initialize in the executable section
-- and remove the controller object but you lose the ability
-- to finalize
end Pretend_Class;
with Pretend_Class;
procedure Test is
package My_Pretend_Class is new Pretend_Class(F_Test_1 => 3.0);
begin
My_Pretend_Class.Set_Total(Amount => 2);
end Test;