Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.12.2010, 15:54   #21
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Цитата:
Сообщение от GunSmoker Посмотреть сообщение
Как не сложно догадаться, ни к чему хорошему это не приведёт. Это всё равно что выдернуть из под человека лестницу, когда он красит стену. Или выгрузить DLL во время выполнения функции в ней.

Почему я и сказал про X, Y, Z. ТС чем-то не тем занимается.
Не спешите с выводами, пусть ТС скажет свое веское слово.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 14.12.2010, 16:13   #22
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,528
По умолчанию

Цитата:
Она использует TObject.Free, а он не динамический и перегрузить ее не удастся.
а зачем его перегружать когда есть
Код:
destructor Destroy; virtual;
надо и можно перегружать destroy;
Free это только оболочка с контролем допустимости
Код:
procedure Tobject.Free;
begin
  if self<>nil then self.Destroy;
end;
Если стоит задача не допускать разрушения объекта пока есть ссылки, то поддерживаю GunSmoker интерфейсы все ссылки должны быть не объектами а интерфейсами. Ну и наследовать свои классы от TInterfacedObject . подсчет ссылок и автоматическое удаление при обнулении числа ссылок уже есть. Это базовый класс при работе с интерфейсами.

Но в данном случае все-таки думаю нужен ГЛОБАЛЬНЫЙ список объектов иначе может возникнуть ситуация повисших закольцованных ссылок (1 ->2 ->1) и никто более на них не ссылается (->утечка памяти).
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 14.12.2010 в 16:20.
evg_m вне форума Ответить с цитированием
Старый 14.12.2010, 21:07   #23
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Цитата:
Сообщение от GunSmoker
Есть подозрение на X, Y, Z. Вы скажите, кто это такие "ещё один указатель" и откуда они берутся.
OK. Ниже приведу пример. И не один.

2 Пепел Феникса
Не годится.
А если мне нужно уничтожить объект прямо сейчас, не дожидаясь пока остальные ссылки от него отключатся.

Цитата:
Сообщение от GunSmoker
Это всё равно что выдернуть из под человека лестницу, когда он красит стену. Или выгрузить DLL во время выполнения функции в ней.
Нет. Здесь все гораздо проще. Был объект нужен - был объект, были на него ссылки. Не стал нужен - и не стало его. А вот ссылочки остались.
А выгружать работающую DLL - это вообще для первоклассников.
У меня-то как раз обратная ситуация. Пока объект нужен, его никто удалять не собирается. Вопрос только в том кому он нужен (опять же, далее поясню).

Цитата:
Сообщение от evg_m
надо и можно перегружать destroy;
Free это только оболочка с контролем допустимости
Согласен. Напутал.

Цитата:
Сообщение от GunSmoker
Интерфейсы для кого придумали?
Цитата:
Сообщение от evg_m
все ссылки должны быть не объектами а интерфейсами
Не могу понять, чем здесь помогут интерфейсы.

----------------------------------------------------------------------
Пример №1 (Инжиниринг)
Нарисована линия. Затем вторая, которая привязалась одним концом к центру первой (таких линий может быть 1000). Если сместить первую линию, то один конец второй сместится за первой. Удобно. Но потом мне понадобилось удалить первую линию (она стала мне не нужна сама по себе), но вторая на нее ссылается.
Взаимосвязи могут быть очень сложными. Представте. Начали проект. Получили техусловия на подключение к электросети, канализации, водопроводу, теплотрассе. Делали, делали. Тут бах (такое бывает) здание переносят в другой угол площадки метров на 100. Техусловия заново получать придется. А у вас отверстия в стенах подвала, опоры, расстановка оборудования, все завязано на техусловиях.

Есть по крайней мере два пути решения:
Способ 1 (Список зависимостей):
При привязке 2 к 1 сохранить в 1, что 2 от нее зависит. При удалении 1 осуществить "правильную" отвязку 2 (координаты привязаной точки станут глобальными).
Способ 2 (Глобальный массив):
Хратить линии в глобальном массиве. А экземпляры 1 и 2 - это ссылки на элементы массива, а не сами объекты линий.
Способ 3 (Страшноватый):
Описанный в посте #1.
Способ 4 (Маразматический):
Похож на первый. Но... Хранить в объекте список всех глобальных ссылок на него. А перед уничтожением объекта присваивать им nil. Правильной отвязки не произойдет, но при следующем обращении к объекту через указатель, я легко смогу проверить его на nil. Как я и сказал, способ маразматический.

----------------------------------------------------------------------
Пример №2 (Физика)
Мальчик держит 2 воздушных шарика на ниточках (шаров и нитей может быть больше и они могут быть связаны). Координаты шариков Z зависят от длины нитей, веса руки мальчика, подъемной силы всех шариков и т.д и т.п. и пр. Одна из ниточек рвется - Удаляется. Именно удаляется. Ведь речь идет не просто о физической системе забитой в программу, а о запрограммированной неким юзером модели. Я этого юзера не знаю и сказать ему, что он должен сначала разорвать все ссылки, а потом удалять объект, не могу.

Решения те же

----------------------------------------------------------------------
Пример №3 (Жизненный)
Мужик стоял на стремянке и красил потолок. Другой (я его тоже не знаю) взял и убрал стремянку. Даже если бы я знал этого мужика, я бы не смог ему это запретить.
Это может быть когда с одним проектом работают несколько пользователей с разных компов. Они периодически синхронизируются.
1. Человек А создал объект 1.
2. Синхронизация
3. Человек Б создал объект 2 зависящий от 1.
4. Человек А удалил объект 1.
5. Синхронизация

Решения те же

Примеров я могу привести 1000. Проблема в том, что решений не меньше. И каждое имеет как + так и -. Нужно ЭЛЕГАНТНОЕ универсальное решение. Своим первым постом я не притендую на элегантность. Это скажем так - для затравки.

P.S.: Спасибо всем кто откликнулся. Вы реально помогаете мне думать. Давайте исчё.
Sibedir вне форума Ответить с цитированием
Старый 14.12.2010, 21:11   #24
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
А если мне нужно уничтожить объект прямо сейчас, не дожидаясь пока остальные ссылки от него отключатся.
а я разве запретил использовать Free?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 14.12.2010, 21:26   #25
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

А зачем тогда счетчик? Все теряет смысл. Или я чет не догоняю.
Sibedir вне форума Ответить с цитированием
Старый 14.12.2010, 21:37   #26
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
а помоему здесь отлично подходят счетчики ссылок.
Не стал все читать, но прочитав вопрос автора, тоже сразу подумал об этом. По сути все просто:
1. новая адрес (переменная) на уже созданный класс? - увеличили ссылку
2. отработали, и более не нужна это переменная - уменьшили ссылку
3. т.к. все от одного класса, в нем храним ссылку, и соответственно два метода на манипуляции с ссылкой.
4. как только ссылка = 0, вызываем Free, т.е. все переменные которые использовали данный экземпляр класса более не нуждаются в нем.
5. На счет резкого сброса, ну тут просто, как и было сказано, вызвать Free, но это чревато самой идей, т.к. если счетчик > 0, то в один прекрасный момент получим обращение к несуществующему объекту.

Надеюсь проблему это решит, т.к. метод стоящий в данной ситуации. Есть конечно еще вариант, применить Singleton, правда тут несколько экземпляров класса, тогда можно сделать какой то список глобальный, к примеру статический у данного класса, как вариант, и потом от него уже плесать.
BOBAH13 вне форума Ответить с цитированием
Старый 14.12.2010, 21:41   #27
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Ну, вот, другое дело. Давайте разбирать предметно.

Цитата:
Нарисована линия. Затем вторая, которая привязалась одним концом к центру первой (таких линий может быть 1000). Если сместить первую линию, то один конец второй сместится за первой. Удобно. Но потом мне понадобилось удалить первую линию (она стала мне не нужна сама по себе), но вторая на нее ссылается.
Взаимосвязи могут быть очень сложными. Представте. Начали проект. Получили техусловия на подключение к электросети, канализации, водопроводу, теплотрассе. Делали, делали. Тут бах (такое бывает) здание переносят в другой угол площадки метров на 100. Техусловия заново получать придется. А у вас отверстия в стенах подвала, опоры, расстановка оборудования, все завязано на техусловиях.
Линия, я так понимаю, - компонент? Открываем для себя метод FreeNotification и Notification.

Далее, пример №2 анализу не поддаётся, так как не сказано, что здесь является объектом, а что - состоянием объекта. Где куда какая ссылка вписывается - тоже не ясно.

Пример 3 аналогичен примеру 1.

Цитата:
Не могу понять, чем здесь помогут интерфейсы.
Есть два класса. Объекты второго класса могут ссылаться на объекты первого класса, используя свойство, например:

Код:
type
  TMyEmbeddedClass = class
    // ...
  end;

  TMyClass = class
    // ...
  public
    // ...
    property Embedded: TMyEmbeddedClass read FEmbedded write FEmbedded;
    // ...
  end;
Вы озвучили проблему:

Код:
var
  InternalObj: TMyEmbeddedClass;
  ExternalObj: TMyClass;
begin
  InternalObj := TMyEmbeddedClass.Create;
  ExternalObj := TMyClass.Create;

  ExternalObj.Embedded := InternalObj;

  FreeAndNil(InternalObj);

  // что делать с ExternalObj.Embedded ???
  
end;
Интерфейсы решают эту проблему: пока на объект кто-то ссылается, объект не удаляется:

Код:
type
  IMyEmbeddedClass = interface
    // ...
  end;

  IMyClass = interface
    // ...
    property Embedded: IMyEmbeddedClass read GetEmbedded write SetEmbedded;
    // ...
  end;

  TMyEmbeddedClass = class(TInterfacedObject, IInterface, IMyEmbeddedClass)
    // ...
  end;

  TMyClass = class(TInterfacedObject, IInterface, IMyClass)
    // ...
  end;

var
  InternalObj: IMyEmbeddedClass;
  ExternalObj: IMyClass;
begin
  InternalObj := TMyEmbeddedClass.Create;
  ExternalObj := TMyClass.Create;

  ExternalObj.Embedded := InternalObj;

  InternalObj := nil; // объект InternalObj пока живёт, потому что на него ссылается ExternalObj.Embedded

  ExternalObj := nil; // уходят и ExternalObj и InternalObj.
  
end;
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 14.12.2010, 22:02   #28
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Цитата:
Сообщение от Sibedir Посмотреть сообщение
Способ 3 (Страшноватый):
Описанный в посте #1.
Способ 4 (Маразматический):
Похож на первый. Но... Хранить в объекте список всех глобальных ссылок на него. А перед уничтожением объекта присваивать им nil. Правильной отвязки не произойдет, но при следующем обращении к объекту через указатель, я легко смогу проверить его на nil. Как я и сказал, способ маразматический.
Слабо представляю как выделяется память при создании объекта. Для переменных вроде прозрачно. Код - не должен дублироваться, но вот адресовка методов - не исключаю, что определенная память используется. Поэтому способ 3 для меня страшен в квадрате.

А вот маразматический способ привлек внимание. Указателю не присваивать адрес объекта, а в объекте предусмотреть метод с var-параметром этого указателя, т.е. присвоение внутри объекта с одновременным запоминанием адеса указателя в массив, который nil-лить при Free
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 15.12.2010, 06:27   #29
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

2 BOBAH13 и GunSmoker
На счет интерфейсов и счетчиков.
Так? (на сколько я это понял). В экземпляре установить дополнительное поле (FDeleted) или создать 2 глобальных списка (ActingList и DeletedList). Если, скажема, удаляем линию, то устанавливаем ей свойство Deleted = True. При отвязки ссылки уменьшаем счетчик (если счетчик стал = 0 -> уничтожаем объект). При обращении к экземпляру проверяем свойство Deleted. Если Deleted = True, производим "правильную" отвязку, уменьшаем счетчик и обниливаем ссылку на "какбэ удаленный" объект.

Вопрос. Отличается ли работа с экземплярами интерфейса от работы с экземплярами обычных классов на низком уровне (я, конечно же, имею в виду производительность). Просто не вижу смысла использования именно интерфейсов. Счетчик прикрутить к классу - минутное дело.

Цитата:
Сообщение от GunSmoker
Линия, я так понимаю, - компонент?
Думаю использование компонента излишне. Нет, линия - это класс потомок от TSibObject.
Вводится:
- для обеспечения общности предка всех объектов (консенсус м/у грамоздким TComponent и нефункциональным и разобщенным использованием множества разных потомков TObject)
- для единообразия храниения данных (обеспечивается единый механизм сохранения, загрузки, конвертации)
- для обеспечения работы еще нескольких общих механизмов (удаление, логические и математические взаимосвязи, отслеживание изменений и пр.)

P.S.: Блин. Опять 25. Ща все переделаю к чертям, а потом, через пару месяцев, подумаю: "Чё за херня? Надо все по другому."

--------------------------------------------------
http://softwarer.nm.ru/memory.html - не плохая статейка

Последний раз редактировалось Sibedir; 15.12.2010 в 08:26.
Sibedir вне форума Ответить с цитированием
Старый 15.12.2010, 07:07   #30
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Цитата:
Не стал все читать, но прочитав вопрос автора, тоже сразу подумал об этом. По сути все просто:
Вот и напрасно - ТС требуется удаление объектов не в определенной последовательности, а так как вздумается высшим силам (пользователю).
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Неправильно выделена память. С++ Purr Помощь студентам 7 31.10.2010 20:05
Как передвигать объект если он не под формой.VB somebody94 Помощь студентам 1 29.06.2010 10:07
Объект PageSetup. Как проверить пустые ли колонтитулы в документе Word?? =) YaponskijGorodovoj Компоненты Delphi 0 09.06.2010 23:09
динамически выделить память под верхний треугольник квадратной матрицы juventine Общие вопросы C/C++ 2 12.04.2009 13:06
Память, выделяемая под приложение. Altera Компоненты Delphi 4 30.11.2008 18:13