adagnat

Create a record with a private part


According to this post, I'v try to do a record with a private part. What I've done :

MyFile.ads :

package MyPackage is
  type T_MyType is tagged private;
private
  type T_MyType_Private_Part;
  type T_MyType_Private_Part_Access is access T_MyType_Pirvate_Part;
  type T_MyType is tagged record
    Toto : Boolean;
  end record
end MyPackage;

MyFile.adb :

package body MyPackage is
   type T_MyType_Private_Part is record
     Private_Toto : Boolean;
   end record
end MyPackage;

But when an other package do MyVar.Toto where MyVar is T_MyType I have the error :

no selector "Toto" for type "T_MyType" defined at MyFile.ads

How can I fix this ?


Solution

  • It is very simple to produce a record with a private part using Ada.

    The following example declares a base tagged type with a public member. It then creates a child package which extends the tagged type with private members. The type declared in the child package has both a public and private data members.

    with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
    
    package base_type is
       type base is tagged record
          Name : Unbounded_String;
       end record;
    end base_type;
    

    The package named base_type declares a tagged record with a public member. The

    package base_type.person is
       type gender is (male, female);
       type weights is new Float range 0.0 .. 500.0;
    
       type person_type is new base with private;
    
       procedure set_gender (P : in out person_type; G : in gender);
       procedure set_weight (P : in out person_type; W : in weights);
       procedure Print (P : person_type);
    
    private
       type person_type is new base with record
          G : gender;
          W : weights;
       end record;
    
    end base_type.person;
    

    The body of base_type.person is

    with Ada.Text_IO; use Ada.Text_IO;
    
    package body base_type.person is
    
       ----------------
       -- set_gender --
       ----------------
    
       procedure set_gender (P : in out person_type; G : in gender) is
       begin
          P.G := G;
       end set_gender;
    
       ----------------
       -- set_weight --
       ----------------
    
       procedure set_weight (P : in out person_type; W : in weights) is
       begin
          P.W := W;
       end set_weight;
    
       -----------
       -- Print --
       -----------
    
       procedure Print (P : person_type) is
          package w_io is new Float_IO(weights);
          use w_io;
       begin
          Put_Line(To_String(P.Name));
          Put_Line ("Gender: " & P.G'Image);
          Put("Weight: ");
          Put(Item => P.W, Fore => 1, aft => 1, Exp => 0);
          New_Line(2);
       end Print;
    
    end base_type.person;
    

    A should be expected, the private data members may only be accessed through procedures and functions.

    A main procedure creating a program example is

    with base_type.person;      use base_type.person;
    with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
    
    procedure Main is
       P1 : person_type;
       P2 : person_type;
    begin
       P1.set_gender (Male);
       P1.set_weight (165.2);
       P1.Name := To_Unbounded_String ("Barney Rubble");
       P2.Name := To_Unbounded_String ("Betty Rubble");
       P2.set_gender (female);
       P2.set_weight (110.5);
       Print (P1);
       Print (P2);
    end Main;
    

    The output of this program is:

    Barney Rubble
    Gender: MALE
    Weight: 165.2
    
    Betty Rubble
    Gender: FEMALE
    Weight: 110.5