Конференция "Прочее" » Queue. Объясните, чего ему ещё надо?
 
  • K-1000 © (03.04.16 19:20) [0]

    var
     Queue: TObjectQueue;

    procedure InitQueue();
    begin
     Queue:= TObjectQueue.Create();

     Queue.Push(TObject.Create());
     Queue.Push(TButton.Create());
     Queue.Push(TBitmap.Create());
    end;

    function GetNextNameOfObjectFromQueue(): String;
    var
     Value: TObject;
    begin
     Value:= Queue.Pop();

     if Assigned(Value) then
     begin
       Result:= String(Value.ClassName);

     end else
     begin
       Result:= '[ EMPTY ]';

     end;
    end;

    procedure TForm1.Button8Click(Sender: TObject);
    begin
     Caption:= GetNextNameOfObjectFromQueue();
    end;



    По идее, если нажимать на кнопку, то в заголовке окна должны прописываться имена классов очереди.
    После последнего элемента выкидывает такое: 'List index out of bounds (-1)'.
    О чего так? Ведь по идее по окончании очереди Pop() должен вернуть nil.
  • Юрий Зотов © (03.04.16 19:46) [1]
    > Ведь по идее по окончании очереди Pop() должен вернуть nil.

    Может вернуть NIL, а может и исключение выбросить (что и делает). Все зависит от реализации.
  • Eraser © (03.04.16 19:47) [2]

    > Ведь по идее по окончании очереди Pop() должен вернуть nil.

    видимо нет. см. исходник.
  • Dimka Maslov © (03.04.16 20:28) [3]
    Именно поэтому не стоит пользоваться подобными библиотеками и фреймворками - они могут выкинуть всё что угодно.
  • sniknik © (03.04.16 20:37) [4]
    > они могут выкинуть всё что угодно.
    хелп/исходники же есть...

    function GetNextNameOfObjectFromQueue(): String;
    begin
     if Queue.Count > 0
       then Result:= Queue.Pop().ClassName
       else Result:= '[ EMPTY ]';
    end;

  • Dimka Maslov © (03.04.16 20:47) [5]

    > хелп/исходники же есть...


    Хелп, созданный автоматической помощесоздалкой, который на 95% состоит из записей This is so-and-so method... Действительно серьёзное подспорье в использовании кода. Тем более, что так ничего и не понятно, почему очередь выкидывает исключение вместо возврата нуля...
  • sniknik © (03.04.16 20:48) [6]
    хотя правильнее будет так:
    function GetNextNameOfObjectFromQueue(): String;
    begin
     if Queue.Count = 0
       then Result:= '[ EMPTY ]'
       else
         with Queue.Pop() do begin
           Result:= ClassName;
           Free;
         end;
    end;

  • sniknik © (03.04.16 20:51) [7]
    > который на 95% состоит из записей This is so-and-so method...
    ну, не знаю, у меня нормальный

    TObjectQueue
    Hierarchy Methods See also
    TObjectQueue maintains a first-in first-out list of objects.
    Unit
    Contnrs
    Description
    Use a TObjectQueue to store and maintain a first-in first-out list of objects.

    Removes and returns the object at the front of the queue.

    Delphi syntax:
    function Pop: TObject;
    C++ syntax:
    HIDESBASE System::TObject* __fastcall Pop(void);

    Description
    Call Pop to retrieve an object from the queue. Pop removes the next object from the queue (that is, the earliest object added), then returns a reference to the deleted object.
    To access the queue without removing an object, call Peek.
  • Юрий Зотов © (03.04.16 21:10) [8]
    > Dimka Maslov ©   (03.04.16 20:47) [5]

    > почему очередь выкидывает исключение вместо возврата нуля

    Потому что NIL может сидеть в очереди. И если вместо исключения выдать NIL, то будет непонятно - то ли очередь пуста, то ли в ней NIL сидел. А с исключением все однозначно.
  • K-1000 © (03.04.16 21:59) [9]

    > sniknik ©   (03.04.16 20:48) [6]
    > хотя правильнее будет так:
    > function GetNextNameOfObjectFromQueue(): String;
    > begin
    >  if Queue.Count = 0
    >    then Result:= '[ EMPTY ]'
    >    else
    >      with Queue.Pop() do begin
    >        Result:= ClassName;
    >        Free;


    А зачем вызывать Free() ведь Pop() удаляет объект из очереди?
  • K-1000 © (03.04.16 22:00) [10]

    > Юрий Зотов ©   (03.04.16 21:10) [8]
    > > Dimka Maslov ©   (03.04.16 20:47) [5]
    >
    > > почему очередь выкидывает исключение вместо возврата нуля
    >
    > Потому что NIL может сидеть в очереди. И если вместо исключения
    > выдать NIL, то будет непонятно - то ли очередь пуста, то
    > ли в ней NIL сидел. А с исключением все однозначно.


    Точно! Что-то этот момент упущен был извиду. :)
  • DVM © (03.04.16 22:11) [11]

    > А зачем вызывать Free() ведь Pop() удаляет объект из очереди?
    >
    >
    >

    Если объект далее нужен, то Free конечно не нужно вызывать. Pop() только удаляет из очереди его, сам объект нужно уничтожать как обычно.
  • DVM © (03.04.16 22:13) [12]
    Вообще про nil в очереди конечно такое возможно, но на практике маловероятно, ибо проще не класть nil в очередь, чем потом проверять.
  • Dimka Maslov © (03.04.16 22:18) [13]

    >
    > Потому что NIL может сидеть в очереди


    Я бы ни за что не стал пихать nil в очередь. Лучше создать "пустой" объект, нежели потом AV отлавливать.
  • Юрий Зотов © (03.04.16 23:16) [14]
    > DVM ©   (03.04.16 22:11) [11]
    > Dimka Maslov ©   (03.04.16 22:18) [13]


    NIL в очереди (да и вообще в любом списке объектов) может быть значимым для алгоритма. Хотя я бы тоже от такого алгоритма, скорее всего, постарался  бы воздержаться, но задачи разные бывают и NIL в списке может оказаться вполне удачным решением.
  • Dimka Maslov © (04.04.16 08:18) [15]

    > NIL в очереди (да и вообще в любом списке объектов) может
    > быть значимым для алгоритма


    var
     NilObject: TObject;

    initialization
     NilObject := TObject.Create;

    после чего сравниваем с этим объектом на предмет пустоты объекта и с nil на предмет окончания очереди. При этом более не нужна проверка на количество объектов.
  • Игорь Шевченко © (04.04.16 10:39) [16]
    Dimka Maslov ©   (04.04.16 08:18) [15]

    Я не до конца понимаю, зачем гордиться костылями ?
  • Dimka Maslov © (04.04.16 13:29) [17]

    > Игорь Шевченко ©   (04.04.16 10:39) [16]


    А в чём собственно костыль?
  • Юрий Зотов © (04.04.16 16:34) [18]
    > Dimka Malov ©   (04.04.16 13:29) [17]

    1. Заменили одну проверку другой. Стало лучше? Нет, стало хуже. Потому что сама проверка как была, так и осталась, только во втором варианте еще и спецобъект надо создавать (который, насколько я понял Игоря, костыль и есть).

    3. В проект приходит новый разработчик, которому об этом спецобъекте забыли сообщить (100%, что так и будет). Бедняга честно пишет правильный код и не может понять, что за чудеса происходят в программе.
  • Dimka Maslov © (04.04.16 21:49) [19]

    > Юрий Зотов ©   (04.04.16 16:34) [18]


    1. Мы получили указатель и сравниваем его с нулём, как признаком окончания списка или с пустым объектом, что означает, что никакие действия не нужны. При этом не надо ещё каждый раз проверять количество объектов очереди - вот лишняя и ненужная проверка. Более того, отсутствие в списке нулей избавляет от AV когда по недосмотру объект убежит туда, где его не будут проверять, либо сама проверка уже даст ошибку.

    2. Сложно представить, что здеся было.

    3. Правильный код - это тот, который правильно работает, а не который написан именно так, как сказано "в теории".
 
Конференция "Прочее" » Queue. Объясните, чего ему ещё надо?
Есть новые Нет новых   [134434   +28][b:0][p:0.001]