ada - 在 Ada 中使用私有(private)类型创建私有(private) int

标签 ada

我正在尝试在 Ada 中实现私有(private)类型,就像在 Java 或 C++ 中使用的那样。例如,我想在 Ada 中有一个“private int”。

正如我在这里找到的 http://en.wikibooks.org/wiki/Ada_Programming/Object_Orientation#Encapsulation:_public.2C_private_and_protected_members我必须在包体中实现我的变量。因此,我尝试按照示例中的描述来实现这一点。

我的问题是我无法创建用于创建对象和设置值的 Create 函数。我的第二个问题是我想要这样的 child 。这些 child 应该有一个 Create 函数来设置主类和子类的值。

这是我的代码,它不起作用。我已经对不起作用的点添加了评论。

private with Ada.Finalization;
package MasterClass is
    type MasterC is tagged private;    
    type MasterC_Class_Ref is access all MasterC'Class;
    procedure printNumObjects;
    procedure do( This : in MasterC );
    function Make (f1, f2 : Float) return MasterC;
    function getVar(This : MasterC) return float;  
private
    type Private_Part;  -- declaration stub
    type Private_Part_Pointer is access Private_Part;

    type Private_Component is new Ada.Finalization.Controlled with record
        P: Private_Part_Pointer;
    end record;
    overriding procedure Initialize (X: in out Private_Component);
    overriding procedure Adjust     (X: in out Private_Component);
    overriding procedure Finalize   (X: in out Private_Component);

    type MasterC is tagged record
        P : Private_Component;
    end record;
end MasterClass;

package body MasterClass is
    numObjects : Integer := 0;      
    type Private_Part is record  -- complete declaration
        fTest1, fTest2 : float := 0.0;
    end record;

    overriding procedure Initialize (X: in out Private_Component) is
    begin
        X.P := new Private_Part'(fTest1=>0.0, fTest2 => 0.0);
    end Initialize;

    overriding procedure Adjust (X: in out Private_Component) is
    begin
        X.P := new Private_Part'(fTest1 => X.P.fTest1, fTest2 => X.P.fTest2);
    end Adjust;

    overriding procedure Finalize (X: in out Private_Component) is
        procedure Free is new Ada.Unchecked_Deallocation (Private_Part, Private_Part_Pointer);
    begin
        Free (X.P);
    end Finalize;
        
    function Make (f1, f2 : Float ) return MasterC is   
    begin
        numObjects := numObjects + 1;
        return new MasterC'(fTest1=>0.0, fTest2=>0.0); -- This is not working!      
    end Make;

    procedure do( This : in MasterC ) is
    begin
        Put_Line( "doneMaster");
    end do;
    
    function getVar( This : MasterC )
        return float is
    begin
        return This.P.P.fTest1;  -- This is not working!
    end getVar; 
end MasterClass;

with MasterClass; use MasterClass;
package SubClass is 
    type SubC is new MasterClass.MasterC with 
        record
            fExtra1 : float := 0.0;
            fExtra2 : float := 0.0;
        end record;     
    type SubC_Class_Ref is access all SubC'Class;   
    overriding procedure do(This : SubC);
    function Make (f1, f2 : Float) return SubC; 
    function Make1 (f1, f2 , w, h: Float) return SubC;
end SubClass;

with MasterClass; use MasterClass;
package body SubClass is
    function Make ( f1, f2 : Float ) return SubC is
    begin       
        return ((fTest1 => f1, fTest2 => f2, fExtra1 => 0.0, fExtra2 => 0.0));      
    end Make;

    function Make1 ( f1, f2, w, h: Float ) return SubC is
    begin       
        return (fTest1 => f1, fTest2 => f2, fExtra1 => w, fExtra2 => h);        
    end Make1;

    overriding procedure do( This : in SubC ) is
    begin
        do(MasterC(This));
        Put_Line( "doneSub");
    end do;
end SubClass;

我找不到任何关于如何实现它的信息。

我不知道如何实现的行是 Make 函数中的返回行

return new MasterC'(fTest1=>0.0, fTest2=>0.0); -- This is not working!

然后是读取值的行

return This.P.P.fTest1;  -- This is not working!

然后是子类的 Make 函数中的行。

return ((fTest1 => f1, fTest2 => f2, fExtra1 => 0.0, fExtra2 => 0.0)); -- This is not working!      

最佳答案

ajb 的回答非常 很好,但我希望您允许我“努力”使用 Ada 的 OOP 工具,因为它们实际上与 Java 有很大不同等价物。 -- 我在这里打字,所以这些例子可能无法编译,但应该这样做来理解这些想法。

Package Test_1 is
  Type Point is record
   x, y : Integer;
  end record;
  -- Some operations
End Test_1;

在上面我们创建了一个类型,但这里有一个问题:它暴露了实现,用户可以直接去更改值,如果需要确保某些过程/属性,这可能是灾难性的。 (它还引入了对实现细节的依赖。)

为了解决这个问题,我们可以将记录设为私有(private),并让客户端使用函数和过程来更改内部状态——就像 getter 和 setter 一样(但我们还没有触及任何 OOP)。

Package Test_2 is
  Type Point is private;

  Function Create( x, y : Integer ) return Point;
  Function Get_X ( P : Point ) return Integer;
  Function Get_Y ( P : Point ) return Integer;
  -- Some more operations.
Private
  Type Point is record
   x, y : Integer;
  end record;

  -- Ada 2012 expression-functions, for brevity.
  Function Create( x, y : Integer ) return Point is ( x => x, y => y );
  Function Get_X ( P : Point ) return Integer is ( P.X );
  Function Get_Y ( P : Point ) return Integer is ( P.Y );
End Test_2;

在上面进行了更改,以便实现是私有(private)的,这允许我们更改实现(见下文)而无需强制客户端重新编译。 (我们可以将 Test_3 更改为 Test_2,它仍然有效。)

Package Test_3 is
  Type Point is private;

  Function Create( x, y : Integer ) return Point;
  Function Get_X ( P : Point ) return Integer;
  Function Get_Y ( P : Point ) return Integer;
  -- Some more operations.
Private
  Type Point is record
   x, y : Float;
  end record;

  -- Ada 2012 expression-functions, for brevity.
  Function Create( x, y : Integer ) return Point is
  ( x => Float(x), y => Float(y) );
  Function Get_X ( P : Point ) return Integer is
  ( Integer(P.X) );
  Function Get_Y ( P : Point ) return Integer is
  ( Integer(P.Y) );
End Test_3;

因此,如您所见,private 在 Ada 中的含义与在 Java 中的含义不同。因为 Ada 在添加 OOP 之前(在 Ada 95 中)具有 private 的概念,所以它被带到了 OOP 中。 (基本上这个想法是,私有(private)类型的实现中的更改不会导致程序更改状态,从而导致合法或非法。)

如您所见,Ada 也有记录和间接访问 [私有(private)类型] 甚至继承 [派生类型] 的概念......但 Ada 仍然有类型的概念,尤其是可以禁止的不同类型相互作用(一种长度类型和另一种重量类型)和子类型 [具有附加约束的类型] 差异很大,因此不太适合,因此他们需要一些方法来区分类型和“类型” -or-something-derived-from-it”,这是 'class 属性的来源:Type_Name'Class 表示 的继承树的整个分支>标记类型

-- Declare an operation that must be overridden in derived types,
-- and which takes the specific type:
Function Operation( Input : Type_Name ) return Boolean is abstract;

-- Declare an operation that takes the whole class: 
Function Operation( Input : Type_Name'Class ) return Boolean;

由于上述规则,具有一些私有(private)组件的记录需要位于规范的私有(private)部分,以便对其内部结构的更改不会影响客户端的合法性。

现在我们所处的点与您在 Java 中习惯的点大致相似:类定义和继承,但是增加了 private 是处理客户端使用的东西(和包),而不是,严格来说,对象(或类型)本身。

关于ada - 在 Ada 中使用私有(private)类型创建私有(private) int,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21128964/

相关文章:

c++ - Ada 中的 placement new 相当于什么?

linux - "Event_Mask"的大小太小,允许的最小值为 64

sockets - GNAT.Sockets获取MAC地址

c++ - 声明全局常量和在使用它的函数内部声明常量有什么区别

Ada 通用平均函数

ada - 让 gprbuild 默认为并行构建?

java - 将字符串数据从 Java/Erlang 发送到 Ada

record - Ada 中的歧视记录是什么?

oop - Ada Finalization Adjust 程序 - 放在这里什么?

visibility - 从子包中隐藏记录