Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не дать удалить элемент из TObjectList 
:(
    Опции темы
kami
Дата 8.5.2010, 00:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 22
Всего: 72



Имеется наследник TObjectList с несколькими (от 1 до 50) объектами в нем. Его планируется использовать в нескольких проектах.
Один из элементов этого списка (его индекс может варьироваться) удалять/заменять нельзя под страхом смертной казни (а в процессе разработки я могу забыть про это и нарваться на грабли, посему хотелось бы сразу избежать их).

Собственно - вопрос: как бы правильно (и красиво) обыграть это?

Простое перекрытие TList.Delete(index) результата не даст (т.к. вызывается в том числе и в деструкторе TList через SetCount(0)), а есть еще:
TList.Put; 
TList.SetCount(0), в котором отвратительная строчка FCount := NewCount; 
TList.Extract, в котором сперва объект исключается из списка, а потом вызывается TList.Delete(i); 
Assign и т.п (дальше просто не стал смотреть).

Заранее спасибо за участие.

Это сообщение отредактировал(а) kami - 8.5.2010, 01:08
PM MAIL WWW   Вверх
bems
Дата 12.5.2010, 04:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 18
Всего: 88



Сложно так вот в общем. 
А можно ли чтобы изменялся его индекс в результате удаление предыдущих? 
Чем не подходит выриант с перекрытием деструктора?
Почему бы не использовать Assert в местах, где наличие этого объекта необходимо?


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Rennigth
Дата 12.5.2010, 05:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 15
Всего: 76



kami, А как тебе такой вариант, особо не тестировал но...
Код

unit Unit6;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Contnrs;

type
  TSomeObjLst = class(TObjectList)
  private
    Fobj: TObject;
  protected
    procedure Notify(Ptr: Pointer; Action: TListNotification); override;
  public
    property obj: TObject read Fobj write Fobj;
  end;

  TForm6 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private

  end;

var
  Form6: TForm6;

implementation

{$R *.dfm}

procedure TForm6.FormCreate(Sender: TObject);
var
  lSomeOL: TSomeObjLst;
  lObj: TObject;
begin
  lObj := TObject.Create;
  try
    lSomeOL := TSomeObjLst.Create;
    try
      lSomeOL.Add(lObj);
      lSomeOL.obj := lObj;
      lSomeOL.Remove(lObj);
      //тут lObj существует
    finally
      lSomeOL.Free;
    end;
  finally
    lObj.Free;
  end;
end;

{ TSomeObjLst }

procedure TSomeObjLst.Notify(Ptr: Pointer; Action: TListNotification);
begin
  if not ((Action = lnDeleted) and (Ptr = obj)) then
    inherited;
end;

end.




--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
kami
Дата 12.5.2010, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 22
Всего: 72



Цитата(bems @  12.5.2010,  04:04 Найти цитируемый пост)
А можно ли чтобы изменялся его индекс в результате удаление предыдущих? 

Конечно. Индекс значения не имеет. У объектов в списке есть поле ID (работает по принципу счетчика). Вот элемент с ID=0 создается автоматически и удаляться не должен. Его положение в списке может варьироваться как угодно (более того, оно, к сожалению, должно варьироваться - в интересах и для удобства пользователя).
Цитата(bems @  12.5.2010,  04:04 Найти цитируемый пост)
Чем не подходит выриант с перекрытием деструктора?

Если честно - не понял... объект с ID=0 должен содержаться в TMyObjectList от создания списка до его (списка) уничтожения. деструктор вроде тут ни при чем - т.к. список является владельцем объектов, то он и должен уничтожать их (вызов Clear в деструкторе TObjectList. Но ведь ничто не мешает вызвать Clear вне деструктора. И благодаря действиям в этом Clear оставить вживых нужный элемент не представляется возможным, нужно только перекрывать. И таких методов, перекрытие которых требуется - куча, я их перечислил в вопросе. Мне думается, должно быть более элегантное решение). 
Цитата(bems @  12.5.2010,  04:04 Найти цитируемый пост)
Почему бы не использовать Assert в местах, где наличие этого объекта необходимо?

Это уже будет игра по последствиям. А нужны превентивные меры.
Цитата(Rennigth @  12.5.2010,  05:07 Найти цитируемый пост)
А как тебе такой вариант,

Не подходит. Нотификация вызывается после удаления из списка  (по крайней мере в D7)
Код

procedure TList.Delete(Index: Integer);
var
  Temp: Pointer;
begin
  if (Index < 0) or (Index >= FCount) then
    Error(@SListIndexError, Index);
  Temp := Items[Index];
  Dec(FCount);
  if Index < FCount then
    System.Move(FList^[Index + 1], FList^[Index],
      (FCount - Index) * SizeOf(Pointer));
  if Temp <> nil then
    Notify(Temp, lnDeleted);
end;


Хотя... ведь можно сразу после удаления добавить его снова, ведь в notify до "попадания" в TObjectList.Notify объект жив...
Это мысль. Спасибо, попробую...
PM MAIL WWW   Вверх
Демо
Дата 12.5.2010, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 7
Всего: 50



Я бы написал свой класс для такого.

Если всё же хочется использовать наследника, то проще всего вынести нужный элемент в поле класса и работать с ним специальными методами.


--------------------
    
PM MAIL ICQ Skype   Вверх
bems
Дата 13.5.2010, 00:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 18
Всего: 88



Цитата(kami @  12.5.2010,  12:52 Найти цитируемый пост)
Это уже будет игра по последствиям. А нужны превентивные меры.
Если код, использующий список под твоим контролем, то этого достаточно, чтобы ты не пропустил момент, когда накосячил. 



--------------------
Обижено школьников: 8
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0453 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.