Eiffel — Как мне сделать мои уроки читабельными?

Я новичок в Eiffel и пытаюсь использовать класс LINKED_LIST для организации экземпляров другого класса "MONOMIO", который я создал. Я добавил функцию для упорядочения этих элементов и использую функции удаления и перемещения курсора, и когда я пытаюсь выполнить код, возникает исключение, говорящее, что содержащиеся объекты должны быть доступны для чтения и записи. Я хотел бы знать, как это сделать, это мой класс:

class
    MONOMIO

feature --Initialization 
    make (coef:INTEGER; expX:INTEGER; expY:INTEGER)
    do
            coeficiente := coef
            exponenteX := expX
            exponenteY := expY
    end
feature
    evaluar(valX: INTEGER; valY: INTEGER): REAL_64
            do
                    Result := coeficiente*(valX^exponenteX)*(valY^exponenteY)
            end;
    coeficiente: INTEGER;

    exponenteX: INTEGER;

    exponenteY: INTEGER;


feature --setter
    set_coeficiente(val: INTEGER)
            do
                coeficiente := val
            end;
end

Я думаю, что исключение возникает из-за этой функции, которую я сделал для класса, который имеет функцию LINKED_LIST[MONOMIO] и называется «contenido»:

simplificar
    local
        tamanio_polinomio: INTEGER -- Número de monomios que tiene el polinomio
        contador: INTEGER
        monomio_a_comparar: MONOMIO -- Auxiliar
        coeficiente_total:INTEGER -- Auxiliar
        indice_monomio_en_revision:INTEGER
    do
        from
            contenido.start
            indice_monomio_en_revision := 0
            tamanio_polinomio := contenido.count
        until
            indice_monomio_en_revision = tamanio_polinomio
        loop
            contenido.start
            contenido.move (indice_monomio_en_revision)
            monomio_a_comparar := contenido.item

            from
                contador := indice_monomio_en_revision
                coeficiente_total := monomio_a_comparar.coeficiente
                contenido.forth
            until
                contador = tamanio_polinomio
            loop
                if
                    (monomio_a_comparar.exponentex = contenido.item.exponentex) and
                    (monomio_a_comparar.exponentey = contenido.item.exponentey)
                then
                    coeficiente_total := coeficiente_total + contenido.item.coeficiente
                    contenido.remove -- Mueve el cursor a la derecha
                    tamanio_polinomio := tamanio_polinomio - 1
                    contador := contador - 1
                else
                    if
                        not contenido.islast
                    then
                        contenido.forth
                    end

                end
                contador := contador + 1
            end
            contenido.start
            contenido.move (indice_monomio_en_revision)
            contenido.item.set_coeficiente (coeficiente_total)
            indice_monomio_en_revision := indice_monomio_en_revision + 1
        end
    end;

Я надеюсь, что кто-нибудь может помочь мне с этой проблемой. Спасибо.


person GiaccomoU    schedule 16.06.2016    source источник
comment
Класс выглядит нормально, я думаю, проблема в коде, который работает с LINKED_LIST. Можете ли вы показать это и сказать нам, какую именно ошибку вы получаете? Это ошибка времени компиляции или ошибка времени выполнения?   -  person Alexander Kogtenkov    schedule 16.06.2016
comment
@AlexanderKogtenkov Это исключение, возникающее во время выполнения, в котором говорится, что оно доступно для чтения: PRECONDITION_VIOLATION поднято, и это связано с требованием LINKED_LIST, которое запрашивает, чтобы содержащийся объект был доступен для чтения   -  person GiaccomoU    schedule 16.06.2016
comment
Не могли бы вы показать код, который приводит к исключению, пожалуйста? (readable — это имя подпункта предварительного условия, оно не связано с вашим классом MONOMIO.)   -  person Alexander Kogtenkov    schedule 16.06.2016
comment
@AlexanderKogtenkov уверен, что когда возникает исключение, оно показывает мне это, это код LINKED_LIST для его элемента функции: item: G -- Current item require -- from TRAVERSABLE not_off: not off require -- from ACTIVE readable: readable do check attached active as a then Result := a.item end end   -  person GiaccomoU    schedule 16.06.2016
comment
Я имею в виду ваш код, а не код LINKED_LIST. Я считаю, что проблема в том, что вы пытаетесь получить доступ к элементу за пределами списка.   -  person Alexander Kogtenkov    schedule 16.06.2016
comment
@AlexanderKogtenkov О, извините, я отредактировал вопрос, вот код   -  person GiaccomoU    schedule 16.06.2016


Ответы (1)


Предположим, у вас есть список с 1 элементом. Затем мы входим во внешний цикл и переходим к первому элементу. Затем мы выполняем contador := indice_monomio_en_revision, который на данный момент все еще является 0, и делаем contenido.forth. Теперь мы вне списка, потому что есть только один элемент. Однако contador = tamanio_polinomio ложно (0 = 1), поэтому мы входим во внутренний цикл и пытаемся получить второй (несуществующий) элемент. БУМ!

Другие проблемы включают в себя:

  • Есть несколько вызовов, таких как contenido.start, за которыми следует contenido.move. Вместо этого вы можете использовать один вызов go_i_th.

  • Вместо того, чтобы подсчитывать количество элементов в списке, я бы посмотрел на функцию after. Он сообщает, когда вы достигаете конца списка. Это упростит логику вашего цикла (например, вызов islast будет удален) и позволит вам удалить некоторые локальные переменные.

Принимая во внимание последний пункт, я бы написал условие внутреннего цикла как

contenido.after

По крайней мере, это позволит избежать сбоя, который вы испытываете. Что касается логики, вам может понадобиться проверить функции start, after, forth и remove, чтобы увидеть, какой эффект они оказывают. Обычный способ написания циклов в таких случаях выглядит так:

from
    l.start
until
    l.after
loop
    ... -- Use l.item
    l.forth
end

В случае remove, возможно, вам не нужно звонить forth.

person Alexander Kogtenkov    schedule 16.06.2016
comment
Но разве функция перемещения не перемещает курсор i вправо? Я хотел оставить его равным нулю, потому что тогда на первой итерации он останется в том же положении, как я понимаю. Поправьте меня, если я ошибаюсь, пожалуйста. Благодарю за советы! - person GiaccomoU; 16.06.2016
comment
Вы правы, я перепутал с go_i_th. Я надеюсь, что текущее объяснение не содержит ошибок. ) - person Alexander Kogtenkov; 17.06.2016