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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вызов деструктора внутри конструктора 
:(
    Опции темы
Демо
Дата 3.6.2010, 15:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(PsiMagistr @  3.6.2010,  13:12 Найти цитируемый пост)
Вы пишите If Assigned(self) then в деструкторе лишняя? Вот тут я не могу понять, почему? Да во Free есть эта встроенная проверка. Но именно Free нигде не вызывается.  До него дело не доходит, просто. Вызывается голый деструктор.А попытка вызвать Free в деструкторе:self.free; вместо inherited Destroy;


Деструктор вызывается только для созданного объекта. т.е. Self существует по-определению.

Далее - предка, для которого нужно было бы вызвать свой деструктор, нет.

Код

type TMyClass = class //Начало описания класса


Код

Destructor TMyClass.Destroy; Реализация деструктора.
Begin
  If Assigned(self) then //Если указатель не равен nil связан с объектом то:
  begin
    ShowMessage('Сейчас вызову деструктор!'); //Даю сообщение и
    Inherited Destroy; //Вызов деструктора предка, освобождение памяти.
  end;
end;


Вместо всего этого достаточно

destructor TMyClass.Destroy;
begin
    ShowMessage('Сейчас вызову деструктор!'); //Даю сообщение и
end;



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


Опытный
**


Профиль
Группа: Участник
Сообщений: 479
Регистрация: 31.12.2009

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



Демо, благодарю. 


Цитата(Демо @  3.6.2010,  15:16 Найти цитируемый пост)
Далее - предка, для которого нужно было бы вызвать свой деструктор, нет.


Забавно. Я полагал, что предок всегда есть (TObject хотя бы).

Правильно ли я вас понял, что невозможно вызвать деструктор для несуществующего объекта?



Мне бы как-то попытаться сделать так, чтобы:



Код

MyObject:= MyClass.Create('test.txt'); // Пытаюсь создать объект.


При отсутствии файла мне мало просто вызвать деструктор. Мне важно, чтобы в MyObject был nil. Но вот как его туда заслать?  Ведь при исключении тут же вызывается деструктор, который разрушает все и в конечном итоге - мусор в MyObject.

Или я не так понимаю?
 


 


Это сообщение отредактировал(а) PsiMagistr - 3.6.2010, 16:50


--------------------
"Арфы нет? Возьмите бубен!

Ребята, будем жить!"

 (с) "В бой идут одни старики"

---

"ИЕ" - один из самых сумасшедших браузеров в нашей галактике.
PM MAIL   Вверх
Mikel
Дата 3.6.2010, 15:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 2



А почему бы не сделать что-н типа:

Код

MyObj:=TMyObj.Create;
if not MyObj.Init 
then FreeAndNil(MyObj)
else ...


Вынести просто ту логику в инит...


--------------------
...so remember, it's better to burn out than to fade away
PM MAIL ICQ   Вверх
PsiMagistr
Дата 3.6.2010, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 479
Регистрация: 31.12.2009

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



Mikel, О, это интересная идея.

А что есть init? Как  я понял свойство проверки инициализации?

P.S. Я очень мало знаком с внутренней структурой объектов. К ООП приступил недавно.


--------------------
"Арфы нет? Возьмите бубен!

Ребята, будем жить!"

 (с) "В бой идут одни старики"

---

"ИЕ" - один из самых сумасшедших браузеров в нашей галактике.
PM MAIL   Вверх
Mikel
Дата 3.6.2010, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 2



Initом я просто обозвал функцию в которую предлагаю тебе вынести всю логику из Create. В Create только создавать объект.


--------------------
...so remember, it's better to burn out than to fade away
PM MAIL ICQ   Вверх
PsiMagistr
Дата 3.6.2010, 16:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 479
Регистрация: 31.12.2009

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



Mikel,  благодарю от души за участие. Понимаете суть моей задачи в чем... Я загорелся идеей фикс зашить в класс всю работу с файлами.

Т.е. Есть файл (или соотвествующая запись в нем) - конструктор загружает данные в поля и создает объект. Нет файла - нет объекта. А в объектном указателе в этом случае - Nil. Причем все это должно крутиться внутри класса. В этом весь смак. Обслужить все внешними проверками можно, но тогда нет особого смысла и в классе. Я хочу выжать максимум универсальности.


--------------------
"Арфы нет? Возьмите бубен!

Ребята, будем жить!"

 (с) "В бой идут одни старики"

---

"ИЕ" - один из самых сумасшедших браузеров в нашей галактике.
PM MAIL   Вверх
Демо
Дата 3.6.2010, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(PsiMagistr @  3.6.2010,  15:39 Найти цитируемый пост)
Забавно. Я полагал, что предок всегда есть (TObject хотя бы).


Нет предка, для которого необходимо вызвать дополнительно деструктор.
Хотя я всегда использую inherited Destroy  в своём коде. Это позволяет никогда не забывать вызывать деструктор предка. 


Цитата(PsiMagistr @  3.6.2010,  15:39 Найти цитируемый пост)
При отсутствии файла мне мало просто вызвать деструктор. Мне важно, чтобы в MyObject был nil. Но вот как его туда заслать?  Ведь при исключении тут же вызывается деструктор, который разрушает все и в конечном итоге - мусор в MyObject.Или я не так понимаю?


CodeMonkey уже писал тебе о том, что перед созданием объекта переменную нужно проинициализировать.

т.е. 

Код

MyObject := nil;
MyObject := TMyObject.Create;

В случае возникновения исключения значение MyObject не изменится.
Не путай псевдопеременную Self с обычной переменной-ссылкой на объект.


Это сообщение отредактировал(а) Демо - 3.6.2010, 17:16


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


Опытный
**


Профиль
Группа: Участник
Сообщений: 479
Регистрация: 31.12.2009

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



Демо, дружище. Именно так я и пытался писать. Более того я писал проверки, чтобы отследить:

Код

procedure TForm1.Button1Click(Sender: TObject);

begin

MyObject:= nil;

MyObJect:=TMyClass.Create('Проба.txt'); 

If MyObject = nil then

ShowMessage('Указатель нулевой!'); //Жду сообщения как пришествия, а оно не спешит...


end;



Это сообщение отредактировал(а) PsiMagistr - 3.6.2010, 17:23


--------------------
"Арфы нет? Возьмите бубен!

Ребята, будем жить!"

 (с) "В бой идут одни старики"

---

"ИЕ" - один из самых сумасшедших браузеров в нашей галактике.
PM MAIL   Вверх
Демо
Дата 3.6.2010, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



А каким образом ты можешь дождаться сообщения, если на строке MyObJect:=TMyClass.Create('Проба.txt');  у тебя возникает исключение, и следующие строки не выполняются?


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


Опытный
**


Профиль
Группа: Участник
Сообщений: 479
Регистрация: 31.12.2009

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



А вот тут я совсем не понял чего-то. Допустим возникает исключение. И что? Оно же в конструкторе возникает. Ну конструктор, ясное дело, обваливается.  Но проверка на nill  не в конструкторе, она внешняя, из программы, в обработчике кнопки. По идее должен был быть переход к след шагу, неужели же обваливается вся процедура, где этот злосчастный конструктор вызван? Но тогда получается что из за исключения в конструкторе вся программа клеит ласты)))







Это сообщение отредактировал(а) PsiMagistr - 3.6.2010, 17:46


--------------------
"Арфы нет? Возьмите бубен!

Ребята, будем жить!"

 (с) "В бой идут одни старики"

---

"ИЕ" - один из самых сумасшедших браузеров в нашей галактике.
PM MAIL   Вверх
bems
Дата 3.6.2010, 17:59 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Демо @  1.6.2010,  20:59 Найти цитируемый пост)
При возникновении в конструкторе исключения будет немедленно вызван деструктор, а объект не будет создан.
Во этом случае код в деструкторе нужно писать, учитывая, что в конструкторе может возникнуть исключение. 
Деструктор нужно писать так всегда. Без исключений.

Цитата(Демо @  2.6.2010,  09:06 Найти цитируемый пост)
class function/procedure - специальный вид функций, которые могут выполняться без создания экземпляра класса, не имеют доступа к ссылке на экземпляр класса (Self).
Self есть, но он указывает на класс, а не наэкземпляр (нету селфа только у статических классовых методов)

Цитата(PsiMagistr @  3.6.2010,  17:36 Найти цитируемый пост)
А вот тут я совсем не понял чего-то. Допустим возникает исключение. И что? Оно же в конструкторе возникает. Ну конструктор, ясное дело, обваливается.  Но проверка на nill  не в конструкторе, она внешняя, из программы, в обработчике кнопки. По идее должен был быть переход к след шагу, а то получается что из за исключения в конструкторе вся программа клеит ласты)))
После выполнения деструктора исключение остаётся необработанным, и поднимается вверх по стеку вызовов (с выполнением всех секций finally), до ближайшего по стеку обработчика (это может быть except или обработчик исключений из TApplication, который просто выводит сообщение)


Это сообщение отредактировал(а) bems - 3.6.2010, 18:01


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


Опытный
**


Профиль
Группа: Участник
Сообщений: 479
Регистрация: 31.12.2009

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



bems, и что вы предлагаете? Вот у меня исключение в конструкторе вызывается и весь обработчик кнопки, где я этот конструктор призвал обваливается. 

Это сообщение отредактировал(а) PsiMagistr - 3.6.2010, 18:31


--------------------
"Арфы нет? Возьмите бубен!

Ребята, будем жить!"

 (с) "В бой идут одни старики"

---

"ИЕ" - один из самых сумасшедших браузеров в нашей галактике.
PM MAIL   Вверх
bems
Дата 3.6.2010, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



PsiMagistr, да, обваливается. Ты видишь в этом что-то плохое?
Если ты знаешь что делать в случае отсутствия файла, то пиши секцию except

Это сообщение отредактировал(а) bems - 3.6.2010, 18:32


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


Эксперт
***


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

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



Цитата(bems @  3.6.2010,  17:59 Найти цитируемый пост)
Деструктор нужно писать так всегда. Без исключений.


Это ещё почему?

Код


{TObject}

destructor TObject.Destroy;
begin
end;

procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;



Цитата(PsiMagistr @  3.6.2010,  18:26 Найти цитируемый пост)
bems, и что вы предлагаете? Вот у меня исключение в конструкторе вызывается и весь обработчик кнопки, где я этот конструктор призвал обваливается. 


Ты не умеешь обрабатывать исключения?

Код

procedure TForm1.Button1Click(Sender: TObject);
begin
  try
    MyObJect:=TMyClass.Create('Проба.txt'); 
  except
    ShowMessage('Ошибка!'); //Жду сообщения как пришествия, а оно не спешит...
  end;
end;



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


Опытный
**


Профиль
Группа: Участник
Сообщений: 479
Регистрация: 31.12.2009

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



Демо, нет. НЕ умею. Честно. Я только к дельфи приступил. С книгой сижу.

 Вот реализация конструктора:

Код

constructor TMyClass.Create(FileName:String);
begin

inherited Create; //Вызов конструктора предка
if FileExists(ExtractFilePath(Application.ExeName)+FileName) = true then //Если файл существует:

begin
Fname := 'Задаем по умолчанию';  //Присвоение полю FName
ShowMessage('Файл есть'); //
end

Else raise Exception.Create('Нет файла!') //Иначе поднимаем исключение. 

end;


Вот только как его обработать, чтоб после выполнения исключения обработчик, где будет вызываться конструктор не обваливался?

В случае отсутствия файла - присвоить указателю на объект nil. Но поскольку я его и так инициализировал с nil а меняться он не должен. то в случае отсутствия можно ничего не делать. Поскольку деструктор возникнет автоматом.

Это сообщение отредактировал(а) PsiMagistr - 3.6.2010, 19:16


--------------------
"Арфы нет? Возьмите бубен!

Ребята, будем жить!"

 (с) "В бой идут одни старики"

---

"ИЕ" - один из самых сумасшедших браузеров в нашей галактике.
PM MAIL   Вверх
Страницы: (4) Все 1 [2] 3 4 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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