У меня есть базовый тип, работа которого заключается в ведении списка предметов.Он имеет функцию не диспетчеризации для добавления элементов в него, а также для получения списка элементов из него.
Типы, полученные из этого базового типа, используют элементы в некоторых диспетчерских подпрограммах.Я уже могу реализовать это, имея базовый тип, содержащий вектор элементов, однако я хотел бы, чтобы массив был статическим, если это возможно.Вот что у меня есть:
base.ads:
package Bases is
type Base (<>) is tagged private; -- I want to hide the size
type Int_List is array (Positive range <>) of Integer; -- as an example
function Create return Base; -- returns an empty Base
function Add_To (This : Base'Class; I : Integer) return Base'Class; -- Append
function Image (This : Base) return String; -- Dispatching example
function List (This : Base'Class) return Int_List; -- Get the data for internal use
private
type Base (Size : Natural) is tagged record
Ints : Int_List (1 .. Size);
end record;
end Bases;
base.adb:
package body Bases is
function Create return Base is (Size => 0, Ints => (others => 0));
function Add_To (This : Base'Class; I : Integer) return Base'Class is
-- This is where I have trouble: "aggregate cannot be of a class-wide type"
Copy : Base'Class := (This with Size => This.Size + 1, Ints => This.Ints & I);
begin
return Copy;
end Add_To;
function Image (This : Base) return String is ("BASE");
function List (This : Base'Class) return Int_List is (This.Ints);
end Bases;
производные .ads:
with Bases;
package Deriveds is
type Derived is new Bases.Base with null record;
function Create return Derived;
function Image (This : Derived) return String;
end Deriveds;
производные.adb:
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
package body Deriveds is
function Create return Derived is (Bases.Create with null record);
function Image (This : Derived) return String is
Result : Unbounded_String;
Ints : Bases.Int_List := This.List;
begin
for I in Ints'Range loop
Result := Result & Integer'Image (Ints (I));
end loop;
return To_String (Result);
end Image;
end Deriveds;
Опять же, я знаю, что если я просто удаляю дискриминант и использую управляемый тип для хранения массива, то я могу просто создать копию как Copy : Base'Class := This;
имутируйте его перед возвратом.Однако я чувствую, что должен быть способ сделать это только со статической памятью, что является желательным.Единственный другой обходной путь, о котором я мог подумать, - это создать еще один теговый тип, который будет представлять собой запись, содержащую список и данные Base'Class
и чьи операции будут скрывать Base
диспетчерские операции, передавая их через,
Нет ли способа создать Copy
в Add_To
, чтобы его дискриминант был на 1 больше и имел дополнительный элемент, использующий только статическую память?