Oop Ada中标记记录中的私有属性

Oop Ada中标记记录中的私有属性,oop,ada,gnat,Oop,Ada,Gnat,从面向对象的范例思考,人们如何为标记的记录实现私有属性 目前,从我所看到的,唯一的方法是拥有一个私有类型的属性 比如说 type car is tagged record i_am_a_public_attribute : Integer; i_am_another_public_attribute : Integer; my_private_attributes : t_private_attributes; end record; type car_public is tagg

从面向对象的范例思考,人们如何为标记的记录实现私有属性

目前,从我所看到的,唯一的方法是拥有一个私有类型的属性

比如说

type car is tagged record
  i_am_a_public_attribute : Integer;
  i_am_another_public_attribute : Integer;
  my_private_attributes : t_private_attributes;
end record;
type car_public is tagged record
  i_am_a_public_attribute : Integer;
  i_am_another_public_attribute : Integer;
end record;

type car_private is new car_public with record
  my_private_attributes : Integer;
end record;
其中t_private_属性在包的私有部分声明

例如,我想到的第二种方法是使用继承

type car is tagged record
  i_am_a_public_attribute : Integer;
  i_am_another_public_attribute : Integer;
  my_private_attributes : t_private_attributes;
end record;
type car_public is tagged record
  i_am_a_public_attribute : Integer;
  i_am_another_public_attribute : Integer;
end record;

type car_private is new car_public with record
  my_private_attributes : Integer;
end record;
其中,car_private在包裹的私密部分声明。虽然这个实现我认为会非常混乱

人们是如何做到这一点的


谢谢Matt

< P>,艾达的包的私有部分更接近于C++中的保护,而不是私有的。 但是,大多数情况下,使用私有部分是最好的方法,此外还提供了将单元测试作为子包编写的灵活性,以便它们可以测试类型的属性

如果您真的想使代码的任何其他部分都无法访问这些属性,那么必须在身体中定义它们。这可以通过在包的私有部分声明一个不完整的类型来完成,然后在主体中完成。然后,您的类型将包含指向此不完整类型的指针,如中所示:

package Foo is
    type My_Type is tagged private;
private
   type Private_Part;
   type Private_Part_Access is access Private_Part;
   type My_Type is tagged record
       P : Private_Part_Access;
   end record;
end Foo;
package body Foo is
   type Private_Part is record
      ...
   end record;
end Foo;
这也可以通过使Private_部分成为一个抽象标记的空记录,并在主体中扩展它来实现


当然,这个方案的困难在于内存管理,因为您必须确保您的对象确实会释放相应的内存(可能通过使用受控类型)。

这是Brian Drummond在上面评论中所写内容的扩展。当我用Ada编程语言进行OOP,并希望用一些私有和公共属性来表达“类”的概念时,我会写(使用Matt的示例):

其思想是为每个想要公开的属性都提供一个get函数。实际上,上面的代码不是我所说的“Ada风格”。要利用Ada的优势,请为每个属性定义一个新类型:

type I_Am_A_Public_Attribute_Type        is new Integer;
type I_Am_Another_Public_Attribute_Type  is new Integer;

type Car_Type is tagged private;

function I_Am_A_Public_Attribute (This : Car_Type)       return I_Am_A_Public_Attribute_Type;
function I_Am_Another_Public_Attribute (This : Car_Type) return I_Am_Another_Public_Attribute_Type;

private

type I_Am_A_Private_Attribute_Type       is new Integer;
type I_Am_Another_Private_Attribute_Type is new Integer;

type Car_Type is tagged
   record
      I_Am_A_Public_Attribute        : I_Am_A_Public_Attribute_Type;
      I_Am_Another_Public_Attribute  : I_Am_Another_Public_Attribute_Type;
      I_Am_A_Private_Attribute       : I_Am_A_Private_Attribute_Type;
      I_Am_Another_Private_Attribute : I_Am_Another_Private_Attribute_Type;
   end record;

function I_Am_A_Public_Attribute (This : Car_Type)       return I_Am_A_Public_Attribute_Type        is (This.I_Am_A_Public_Attribute);
function I_Am_Another_Public_Attribute (This : Car_Type) return I_Am_Another_Public_Attribute_Type  is (This.I_Am_Another_Public_Attribute);
请注意,如果将get函数与错误的属性混合使用,则会出现编译时错误。这是“Ada,在我们信任的强类型中”的一个很好的例子


编辑:我曾经调查过,从性能角度看,在公共属性和get函数之间的选择上是否有任何偏好。我发现在使用GNAT编译器时,性能没有差别。我没有在其他编译器上尝试过同样的实验。

类型car被标记为private
并仅为公共属性提供访问器。停止将公共属性设置为负值作为开始。。。