使用Array_List检查Eiffel中的断言违例

时间:2016-01-15 00:28:15

标签: eiffel

CUSTOMER类

class
    CUSTOMER
create
    make

feature{NONE} -- Creation

make(a_name:STRING)
        -- Create a customer with an `account'
    local
        l_account: ACCOUNT
        l_name: IMMUTABLE_STRING_8
        l_bank: BANK
    do
        l_name := a_name
        name := l_name
        create l_account.make_with_name (a_name)
        create l_bank.make
        b := l_bank
        account := l_account
    ensure
        correct_name: name ~ a_name
        correct_balance: balance = balance.zero
    end

feature -- queries

name: IMMUTABLE_STRING_8

balance: VALUE
    do
        Result := account.balance
    end

account: ACCOUNT

b: BANK




 invariant
    name_consistency: name ~ account.name
    balance_consistency: balance = account.balance
 end

BANK课程的一部分:

   make  -- make a bank

       do
          count := 0
          create [ARRAY_LIST][CUSTOMER] customers.make(10)
          customers.count.set_Item(10)

       end

   new(name1: STRING) -- add a new customer to bank

       require 
         ....
       local
            c: CUSTOMER
       do
          create c.make(name1)
          customers.extend(c)
          count := count + 1




       ensure
          ...
       end

在尝试将客户放入数组时,我从ARRAY_LIST类中收到检查断言错误。我得到的标签是“valid_index”我不知道为什么它的错误,因为索引是正确的,我设置数组的计数并给出正确的索引。

客户属于CUSTOMER类

银行有客户和客户有帐户

CUSTOMER有一个ACCOUNT类

2 个答案:

答案 0 :(得分:1)

如果你看一下功能`count',你会发现它是一个功能,而不是一个属性。它返回SPECIAL的计数。然后编辑此结果。但是如果你看一下{SPECIAL} .count,它是一个内置的外部例程,而不是属性。所以它可能不受你的影响。 (您可以在调用put_i_th之前测试valid_index以验证这一点。)

Fundamentaly,ARRAYED_LIST是一个LIST,而不是ARRAY(它是一个ARRAY,但这是一个实现细节)。因此,您的算法对于列表无效(您只能使用extend将新项添加到列表末尾,或者使用put_front添加到前面。后者在ARRAYED_LIST上效率低。)

答案 1 :(得分:1)

所提供的代码存在一些问题。

  1. 创作说明

    create {ARRAYED_LIST [CUSTOMER]} customers.make (10)
    

    分配足够的空间来存储10个元素。它还将customers.count设置为0,即列表中当前的元素数。您无需使用自己的count自行跟踪此号码。该代码还建议将属性customers声明为ARRAYED_LIST [CUSTOMER]类型。在这种情况下,没有理由在创建指令中重复该类型。它可以简化为

    create customers.make (10)
    
  2. 将新元素添加到列表时,
  3. customers.count会自动更新。它不应该手动改变。 (并且无法按照其他答案中的说明进行更改。)只是为了了解为什么会出现前提条件违规行为,您可以在调用customers.count之前检查customers.put_i_th的值(在调试器中或通过打印值到控制台)。此时尚未添加任何元素,因此它是0

  4. 由于ARRAYED_LISTLIST的实现,因此应使用LIST的界面添加/删除项目(有助于查看此功能类,包括继承的)。 customers.put_i_th可用于仅替换现有元素(因为其前提条件valid_index建议并且功能评论确认: - 替换i - 条目,如果在索引间隔中,则v)。将新元素添加到列表末尾的特定元素是extend,因此相应的行看起来像

    customers.extend (c)
    
  5. 一般建议是注意功能前提条件和功能注释以及查看类接口(如果您使用的是Eiffel IDE,则会有相应的视图)。这可能需要一些时间,但最终会得到回报。您还可以在Style Guidelines中找到有关命名约定的部分。