ADA - 班级的前提条件

时间:2014-12-17 09:27:02

标签: ada

我正在尝试编译此代码:

function valid(a:Toto'Class; t: Titi) return Boolean with Pre'Class => fonction(a);

GNAT说“aspect”pre'class“只能为标记私有的原始操作指定”

我想这是因为Toto'Class,但我怎么能让它起作用?

1 个答案:

答案 0 :(得分:3)

我认为Pre'ClassPost'Class的目的是指定即使子程序被覆盖也适用的前提条件。

package Pack1 is
    type Base_Type is tagged record ... end record;
    procedure Operation (Obj : Base_Type) with Pre'Class => [condition];
end Pack1;

这意味着如果满足条件,则允许Operation,即使派生类型强加了其他条件。假设一个过程在Base_Type'Class对象上使用此操作:

procedure Something_Else (Obj : Base_Type'Class) is
begin
    -- check to make sure the condition is true
    Obj.Operation;
end Something_Else;

Something_Else不知道Obj的实际类型是什么。但仍可以确保,如果Pre'Class条件为true,则可以执行Operation(即,它满足前提条件)。如果条件只是Pre => [condition],则无法保证这会起作用,因为Obj的实际类型可能是派生类型,并且可以为该派生类型覆盖Operation具有更严格的条件,并且覆盖Operation上的条件将是被检查的条件(因为调用将分派到覆盖的Operation)。使用Pre'Class时,将检查两个条件,并且如果任一条件为真,则操作是允许的(因此派生类型可以减少限制)。但重要的是,Something_Else依赖合同,如果Pre'Class条件为真,那么Operation是允许的。

但是,如果Operation无法覆盖,则无论如何都不重要。在您的示例中,由于Valid的参数为Toto'Class,并且由于(我假设)Titi不是标记类型,因此Valid不是基本操作,因此不是调度操作。

procedure Another_Procedure (Obj : Toto'Class; T : Titi) is
begin
    if Obj.Valid(T) then
        ...
    end if;
end Another_Procedure;

Another_Procedure调用Valid时,它会始终调用您编写的Valid;无论Valid实际上是什么类型,它都不会发送到不同的ObjValid不是调度功能。因此,在它上面放置一个类范围的前提条件是没有意义的。所以语言不允许它。

注意:在只有基本类型和派生类型而不是类型链的简单情况下,Pre'Class表示如果条件<可以执行操作strong>或派生类型的任何前提条件都成功。 Post'Class表示如果条件派生类型的任何后置条件成功,则子程序符合条件。