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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 21.03.2011, 09:36   #1
brabusman
Новичок
Джуниор
 
Регистрация: 21.03.2011
Сообщений: 2
По умолчанию ссылки на классы

Вот столкнулся с таким, если создать класс и назначить две ссылки на этот класс, а потом одну из них освободить методом free, то вторая ссылка будет ссылаться на уже освобождённую ячейку памяти. Метод Assigned по второй ссылке дает true.

Вопрос: Можно ли второй ссылке узнать правильно ли она ссылается?

Код:
procedure TForm1.Button1Click(Sender: TObject);
var Obj1,Obj2:TObject;
begin
  Obj1:=TObject.Create;
  Obj2:=Obj1;             
  Obj1.Free;
  Obj1:=nil;

  if Assigned(Obj2) then   //здесь будет true
             Obj2.Free;                //ошибка, так как попытка освободить 
                                           //память по неправильной ссылке
end;
Не хочется делать какой-то внешний контролирующий орган(класс), который сам будет проверять и освобождать. Предполагается что эти ссылки находятся совсем в разных местах и друг о друге ничего не знают.
brabusman вне форума Ответить с цитированием
Старый 21.03.2011, 09:38   #2
mss
Заблокирован
 
Регистрация: 27.05.2010
Сообщений: 1,099
По умолчанию

Для этого придуманы интерфейсы.
см. TInterfacedObject
mss вне форума Ответить с цитированием
Старый 21.03.2011, 10:20   #3
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

2 mss
Интерфейсы придуманы не для этого.

2 brabusman
Я понимаю о чем вы говорите. Но поймите главное. Если в программе имеет место вариант, когда может идти обращение в уже уничтоженному объекту, то логика построена не верно.

Я понимаю, что не очень наглядно, но конкретно в вашем примере решение в том, что нужно использовать всего одну ссылку на экземпляр. В данном случае две попросту не нужны.
Код:
var Obj1:TMyObject;
begin
  Obj1:=TMyObject.Create;

  Obj.BlaBlaBla;

  Obj1.Free;
  Obj1:=nil;

  if Obj1 <> nil then
             Obj1.Free;
end;
Ну или так
Код:
procedure TForm1.Button1Click(Sender: TObject);
var Obj1,Obj2:TObject;
begin
  Obj1:=TObject.Create;
  Obj2:=Obj1;             
  Obj1.Free;
  Obj1:=nil;

  if Obj1 <> nil then
             Obj2.Free;
end;
Для пущей убедительности: Приведите конкретный пример использования двух ссылок на один экземпляр, когда нельзя определить, что экземпляр уничтожен.

Можно конечно и так извратнуться: http://www.programmersforum.ru/showthread.php?t=127365
Но лично я все-таки предпочел изменить логику

Последний раз редактировалось Sibedir; 21.03.2011 в 10:23.
Sibedir вне форума Ответить с цитированием
Старый 21.03.2011, 11:39   #4
mss
Заблокирован
 
Регистрация: 27.05.2010
Сообщений: 1,099
По умолчанию

Цитата:
Интерфейсы придуманы не для этого
Для чего бы они ни были придуманы, но механизм подсчета ссылок на объект - одна из ключевых функциональностей интерфейсных объектов.

И не надо нести ересь про "нужно использовать всего одну ссылку на экземпляр".
Сколько нужно - столько и можно использовать.
А разрушение объекта при этом следует возложить на реализацию IUnknown._Release.
mss вне форума Ответить с цитированием
Старый 21.03.2011, 11:59   #5
boawinciace
Новичок
Джуниор
 
Регистрация: 21.03.2011
Сообщений: 3
По умолчанию

тратататыы
boawinciace вне форума Ответить с цитированием
Старый 21.03.2011, 12:19   #6
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Цитата:
И не надо нести ересь про "нужно использовать всего одну ссылку на экземпляр".
Согласен, не правильно выразился. Конечно, ссылок может быть и несколько. Но основная должна быть одна. Например, можно несколько компонентов на форме поместить в массив (дублирование ссылки) для более удобного доступа к ним. Но это, скажем так, второстепенные ссылки. Ч/з них можно обращаться к полям и методам компонентов. Но, если какие-то компоненты уничтожены, нужно обязательно обновить массив.

Цитата:
А разрушение объекта при этом следует возложить на реализацию IUnknown._Release.
mss, еще раз приведу пример с линиями чертежа. Вот смотри, есть Линия1 и есть Линия2. Одна из точек Линии2 привязана к центру Линии1. Т.е. хранит ссылку на экземпляр Линии1. Другими словами Линии1.Счетчик = 2. Если удалить Линию1 (Линия1 := nil), то она не удалится, так как счетчик станет = 1, а не 0. Т.е. пока не отвяжем Линию2, Линия1 будет болтаться в памяти.
Интерфейсы здесь не подойдут. Нужно просто правильно организовать систему взаимосвязей.
Про вариант ТС вообще молчу. Там не то что интерфейсы не нужны, там вообще пример изначально не логичный.
Sibedir вне форума Ответить с цитированием
Старый 21.03.2011, 12:27   #7
mss
Заблокирован
 
Регистрация: 27.05.2010
Сообщений: 1,099
По умолчанию

Цитата:
Линия1 будет болтаться в памяти
И пусть себе "болтается".
Если она "болтается", значит она кому-то еще нужна.
А если она этому "кому-то" стала больше не нужна, то этот "кто-то" обязан обнилить интерфейсную ссылку. И объект-линия будет автоматически уничтожен, как только он станет более не нужен ни одному из этих "кто-то".
mss вне форума Ответить с цитированием
Старый 21.03.2011, 12:27   #8
Johnson
кривокодер ;)
Форумчанин
 
Аватар для Johnson
 
Регистрация: 20.06.2008
Сообщений: 707
По умолчанию

Пересматривайте логику без всяких "если". Создание объекта с попированием ссылки на другой объект - по меньшей мере "дурной тон". Либо используйте один класс, либо создавайте два класса.

И освобождать объект лучше по
Код:
FreeAndNil(TObject);
"А как написать праграму?, "ришыти задачьку очинь нада" ©с форума. Жить становится интереснее, жить становится веселее...
{Быть или не быть} {Неуспешный суицид}
Johnson вне форума Ответить с цитированием
Старый 21.03.2011, 12:36   #9
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Цитата:
И пусть себе "болтается".
"Ну и пусть себе" - плохая фраза для программиста
Цитата:
Если она "болтается", значит она кому-то еще нужна.
Да ни кому она не нужна. Когда уничтожается Линия1, точка Линии2 (которая привязывалась к Линии1) должна стать просто глобальной точкой в общей системе координат.
Цитата:
А если она этому "кому-то" стала больше не нужна, то этот "кто-то" обязан обнилить интерфейсную ссылку. И объект-линия будет автоматически уничтожен, как только он станет более не нужен ни одному из этих "кто-то".
OK. А как этот "кто-то" узнает, что ссылка больше не актуальна?

Короче, интерфейсы тут не нужны, а нужно при удалении объекта известить кого следует. А за тем, кого нужно известить, и должен следить программист (а не интерфейс).
ИМХО: На автомате тут не проедешь.

Цитата:
Сообщение от Johnson
Создание объекта с попированием ссылки на другой объект - по меньшей мере "дурной тон". Либо используйте один класс, либо создавайте два класса.
Поясни
( хе-хе, опять 25)

Последний раз редактировалось Sibedir; 21.03.2011 в 13:01.
Sibedir вне форума Ответить с цитированием
Старый 21.03.2011, 13:09   #10
brabusman
Новичок
Джуниор
 
Регистрация: 21.03.2011
Сообщений: 2
По умолчанию

Цель использовать две ссылки это граф. Есть вершины (назовём TNode) и связи между этими вершинами. Каждая вершина имеет массив входящих и исходящих связей (array of TLink).

При уничтожении всего графа, выполняется destroy для каждой вершины, а в этом destroy'e уничтожаются все связи по данной вершине.

Но удалив связь, вторая вершина с которой эта связь выла установлена не знает что связи больше нет.

Сейчас реализовал так, при удалении вершины TNode отправляется сообщение всем соседям "Удалите из своего списка эту связь, но не выполняйте Free", после этого сообщения для всех связей делается free.

Но как-то мудрёно и отлаживать плохо.
brabusman вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ссылки segail Microsoft Office Excel 6 13.10.2009 22:16
Ссылки Принц HTML и CSS 1 31.05.2008 15:46