Страница 1 из 1
Ссылка на объект, уничтожение и проверка на NULL
Добавлено: 04 Ноябрь 2006, 12:47
StillZero
Код: Выделить всё
! описание примера:
! есть достаточно большой класс, работающий примерно по такой же схеме, как и представленный ниже код
! 1. я создаю объект в одной процедуре, передаю его адрес в другую процедуру, в которой этот объект уничтожается.
! 2. при выходе из первой процедуры, есть проверка - уничтожен ли объект, если нет, то я его уничтожаю.
! 3. а клара и говорит, что объект не был уничтожен, при попытке dispose прога валится по GPF.
! данный пример не валится, но процедура Destruct вызывается два раза
! вопросы:
! почему так происходит?
! и как проверять, на то что объект был уничтожен при таком случае?
! примечание: схема передачи объекта в процедуру именно такая, другая схема не устраивает
PROGRAM
MAP
Main()
RefProc(LONG inAddr)
END
GlobalClass CLASS,TYPE ! описание глобального класса
Prop LONG
Construct PROCEDURE
Destruct PROCEDURE
END
code
Main()
Main PROCEDURE
LocalClass &GlobalClass ! ссылка на локальный объект
code
LocalClass &= NEW GlobalClass ! создали локальный объект
LocalClass.Prop = 10 ! присвоили значение свойству
RefProc(address(LocalClass)) ! вызываем другую процедуру и передаем в нее адрес локального объекта
if LocalClass &= NULL ! если объект уже уничтожен
message('= (NULL)') ! то покажем что он уничтожен
else
message('не равно NULL !!!') ! а если еще жив, то убъем
dispose(LocalClass)
end
RefProc PROCEDURE(LONG inAddr) ! процедура, в которой убивается передаваемый объект
ref &GlobalClass ! ссылка
code
ref &= (inAddr) ! сошлемся на тот объект, адрес которого передали
message(ref.Prop) ! на всякий пожарный покажем что там за значение
dispose(ref) ! убъем объект
GlobalClass.Construct PROCEDURE
code
message('Construct')
GlobalClass.Destruct PROCEDURE ! деструктор вызывается в данном примере 2 раза !!!
code
message('Destruct')
Добавлено: 04 Ноябрь 2006, 21:06
Andrew Listiev
Клара какая? На последнем билде шестерки не валиться!
Добавлено: 07 Ноябрь 2006, 14:18
Andrew™
совершенно неправильный код!!!
кто сказал что после DISPOSE(ref), ref - указатель на объект, обNULLится указатель на этот же объект в другой процедуре.
просто LocalClass будет ссылатьcя на несуществующий объект.
твой алгоритм в простом варианте равен следующему:
Код: Выделить всё
a &GlobalClass
b &GlobalClass
CODE
a &= NEW GlobalClass
b &= a
DISPOSE(a) ! а и б это самостоятельные указатели, и при убивании объекта по первому указателю, значение - указатель в b остаётся и следующий код неправильный
IF ~(b &= NULL)
DISPOSE(b)
END
в твоём случае надо делать примерно так:
Код: Выделить всё
! описание примера:
! есть достаточно большой класс, работающий примерно по такой же схеме, как и представленный ниже код
! 1. я создаю объект в одной процедуре, передаю его адрес в другую процедуру, в которой этот объект уничтожается.
! 2. при выходе из первой процедуры, есть проверка - уничтожен ли объект, если нет, то я его уничтожаю.
! 3. а клара и говорит, что объект не был уничтожен, при попытке dispose прога валится по GPF.
! данный пример не валится, но процедура Destruct вызывается два раза
! вопросы:
! почему так происходит?
! и как проверять, на то что объект был уничтожен при таком случае?
! примечание: схема передачи объекта в процедуру именно такая, другая схема не устраивает
PROGRAM
MAP
Main()
RefProc(LONG inAddr)
END
GlobalClass CLASS,TYPE ! описание глобального класса
Prop LONG
Construct PROCEDURE()
Destruct PROCEDURE(),VIRTUAL
END
GlobalClassMgr CLASS
object &GlobalClass
Construct PROCEDURE()
CreateObject PROCEDURE(),*GlobalClass
DeleteObject PROCEDURE()
Destruct PROCEDURE(),VIRTUAL
END
code
Main()
GlobalClassMgr.Construct PROCEDURE
CODE
SELF.object &= NULL
GlobalClassMgr.Destruct PROCEDURE
CODE
SELF.DeleteObject()
GlobalClassMgr.CreateObject FUNCTION
CODE
SELF.DeleteObject
SELF.object &= NEW GlobalClass
RETURN SELF.object
GlobalClassMgr.DeleteObject PROCEDURE
CODE
IF SELF.object &= NULL THEN RETURN.
DISPOSE(SELF.object)
SELF.object &= NULL
Main PROCEDURE
LocalClass &GlobalClass ! ссылка на локальный объект
tmp GlobalClassMgr
code
LocalClass &= tmp.createObject() ! создали локальный объект
LocalClass.Prop = 10 ! присвоили значение свойству
RefProc(address(tmp)) ! вызываем другую процедуру и передаем в нее адрес локального объекта
RefProc PROCEDURE(LONG inAddr) ! процедура, в которой убивается передаваемый объект
ref &GlobalClassMgr ! ссылка
code
ref &= (inAddr) ! сошлемся на тот объект, адрес которого передали
message(ref.object.Prop) ! на всякий пожарный покажем что там за значение
ref.DeleteObject() ! убъем объект
GlobalClass.Construct PROCEDURE
code
message('Construct')
GlobalClass.Destruct PROCEDURE ! деструктор вызывается в данном примере 2 раза !!!
code
message('Destruct')
Добавлено: 07 Ноябрь 2006, 14:21
Andrew™
вот если бы была возможность проверить валидность указателся...
ну ссылается на что то, а это что то есть?
но лучше так как я написал
в твоём случае, если это не в потоках, То можно передавать не по адресу а по указателю, то и проблемы бы не было, т к это была бы одна переменная типа указатель
Добавлено: 07 Ноябрь 2006, 14:27
Andrew™
Andrew™ писал(а):вот если бы была возможность проверить валидность указателся...
ну ссылается на что то, а это что то есть?
сам себе отвечаю - НЕТ, т к может там что то и есть реальное, но УЖЕ может находится по этому адресу совершенно другой объенкт, и в результате всё равно GPF