Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.09.24;
Скачать: [xml.tar.bz2];

Вниз

Чем отличается в классах Free от Destroy?   Найти похожие ветки 

 
Kiloper   (2006-08-09 11:34) [0]

Чем отличается в классах Free от Destroy? Так и так работает?


 
Сергей М. ©   (2006-08-09 11:37) [1]

a.Free есть тот же a.Destroy, но с предварительной проверкой переменной a на nil


 
Kiloper   (2006-08-09 11:39) [2]

спасибо


 
DrPass ©   (2006-08-09 11:56) [3]


> Чем отличается в классах Free от Destroy?

Удерживая клавишу Ctrl, щелкаешь на вызов Free в тексте программы. Очень полезный способ познания


 
Desdechado ©   (2006-08-09 13:00) [4]

Деструктор напрямую вызывать не рекомендуется. Free - это обертка для него...


 
Anatoly Podgoretsky ©   (2006-08-09 19:53) [5]

Free статический метод.
Destroy виртуальный деструктор.


 
Fay ©   (2006-08-10 03:36) [6]

2 Anatoly Podgoretsky ©   (09.08.06 19:53) [5]
> статический метод
В смысле?


 
Loginov Dmitry ©   (2006-08-10 07:48) [7]

> В смысле?


Он есть только у TObject. У потомков метода Free быть не должно. Об этом говорит остутствие директивы virtual


 
Пусик ©   (2006-08-10 09:50) [8]


> Loginov Dmitry ©   (10.08.06 07:48) [7]
> > В смысле?Он есть только у TObject. У потомков метода Free
> быть не должно. Об этом говорит остутствие директивы virtual


Не должно, но может. В этом случае нарушается принцип полиморфизма и у потомка должен быть явно вызван этот метод. В некоторых случаях такая возможность бывает нужна.

 TChild=class(TObject)
   FCanDestroy: Boolean;
   destructor Destroy; override;
   procedure Free;
 end;

destructor TChild.Destroy;
begin
 ShowMessage("Destroy");
 inherited;
end;

procedure TChild.Free;
begin
 if FCanDestroy then inherited Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 Obj: TChild;
begin
 Obj := TChild.Create;
 Obj.FCanDestroy := False;
 Obj.Free;              //Так будет работать, как запланировано(Зависит от FCanDestroy)
 TObject(Obj).Free; //А так в любом случае будет вызван деструктор
end;


В этом примере происходит не перекрытие метода Free, а его замещение.


 
Anatoly Podgoretsky ©   (2006-08-10 09:54) [9]

Fay ©   (10.08.06 03:36) [6]
В смысле что не виртуальный


 
Чапаев ©   (2006-08-10 10:10) [10]


> if FCanDestroy then inherited Free;

Кстати, вот что меня удивляет... Если "inherited Free" заменить на "inherited", всё равно успешно компилируется и выполняется. Насколько я понимаю, inherited без указания "что-именно-inherited" должно бы выполняться только для виртуальных методов, у которых список параметров гарантированно совпадает со списком параметров предка...


 
DrPass ©   (2006-08-10 10:19) [11]


> Насколько я понимаю, inherited без указания "что-именно-
> inherited" должно бы выполняться только для виртуальных
> методов, у которых список параметров гарантированно совпадает
> со списком параметров предка...

Все верно, кроме слова "виртуальных". Inherited выполняется для любых методов, и никакого фокуса в этом нет - вызов-то формируется еще на этапе компиляции.


 
evvcom ©   (2006-08-10 11:50) [12]


> [11] DrPass ©   (10.08.06 10:19)
> Inherited выполняется для любых методов

Для любых методов-процедур. Для методов-функций такое не катит вообще без имени и параметров.


 
Kolan ©   (2006-08-10 12:45) [13]


> Пусик ©   (10.08.06 09:50) [8]

Опять вы за свое :)
Кстати как-то вы мне это уже показывали и я тогда привел пример про виртуальные методы. Что то вроде:

Пример виртуальной функции в Delphi

Язык Delphi тоже поддерживает полиморфизм. Рассмотрим пример:

Объявим два класса. Предка(Ancestor):

TAncestor = class
private
protected
public
  {Виртуальная процедура.}
  procedure VirtualProcedure; virtual;
  procedure StaticProcedure;
end;

и его потомка (Descendant):

TDescendant = class(TAncestor)
private
protected
public
   {Перекрытие виртуальной процедуры.}
  procedure VirtualProcdure; override;
  procedure StaticProcedure;
end;

Как видно в классе предке объявлена виртуальная функция - VirtualProcdure. Чтобы воспользоваться достоинствами полиморфизма её нужно перекрыть в потомке.

Реализация выглядит следующим образом:

{ TAncestor }
 
procedure TAncestor.StaticProcedure;
begin
  ShowMessage("Ancestor static procedure.");
end;
 
procedure TAncestor.VirtualProcdure;
begin
  ShowMessage("Ancestor virtual procedure.");
end;

{ TDescendant }
 
procedure TDescendant.StaticProcedure;
begin
  ShowMessage("Descendant static procedure.");
end;
 
procedure TDescendant.VirtualProcdure;
begin
  ShowMessage("Descendant override procedure.");
end;

Посмотрим как это работает:

procedure TForm2.BitBtn1Click(Sender: TObject);
var
  MyObject1: TAncestor;
  MyObject2: TAncestor;
begin
  MyObject1 := TAncestor.Create;
  MyObject2 := TDescendant.Create;
  try
    MyObject1.StaticProcedure;
    MyObject1.VirtualProcdure;
    MyObject2.StaticProcedure;
    MyObject2.VirtualProcdure;
  finally
    MyObject1.Free;
    MyObject2.Free;
  end;
end;


Дык вот а вы говорили что зачем нужно объявлять так:
MyObject1: TAncestor;
  MyObject2: TAncestor;


И мол почему бы не объявить сразу конкретные типы.

Так вот даю вам ответ:
при создании объекта явно указывается класс. Задание имени класса привя¬зывает вас к конкретной реализации, а не к конкретному интерфейсу. Это может осложнить изменение объекта в будущем. Чтобы уйти от такой про¬блемы, создавайте объекты косвенно.

:)


 
Пусик ©   (2006-08-10 13:06) [14]


> Kolan ©   (10.08.06 12:45) [13]


см. [8].

Не должно, но может. В этом случае нарушается принцип полиморфизма и у потомка должен быть явно вызван этот метод.

PS.
Я знаю, что Земля не круглая, и в Черном море вода не черная.


 
Kolan ©   (2006-08-10 13:11) [15]


> В этом случае нарушается принцип полиморфизма и у потомка
> должен быть явно вызван этот метод

Не это я увидел.
Просто нашел объяснение почему так делать не надо, сразу ту ветку вспомнил. А тут случай выдался.. и другим это рассказать(хотя мож все этои так знают ) :)


 
evvcom ©   (2006-08-10 13:31) [16]

> создавайте объекты косвенно.

Как это? Что за понятие?


 
Kolan ©   (2006-08-10 13:33) [17]


> Как это? Что за понятие?

Продолжение цитаты:
Паттерны проектирования: абстрактная фабрика, фабричный метод, прототип;


 
Kolan ©   (2006-08-10 13:41) [18]

Те не надо обявлять конктреные типы как например тут:

> var
>  Obj: TChild;

А следует делать абстрактных предков. Обявлять переменные как предки, а инстанцировать конктретные экземпляры:
Пример:
var
 S: TStrings;
begin
 S := TStringList.Create;
 try
 {..}
 finally
   Free;
 end;
end;


Чем это полезно? - Тем что если я потом сделаю наследника TStrings, например TMyOwnStringList, то мне нудно будет заменить только строчку выделенную жирным.

А если я написал бы так:
var
 S: TStringList;
begin
 S := TStringList.Create;
 try
 {..}
 finally
   Free;
 end;
end;

То уже в двух местах...
Понятно что это простейший пример. Тут это нестроашно, а в большой системе...


 
Kolan ©   (2006-08-10 13:42) [19]


> инстанцировать конктретные экземпляры

инстанцировать экземпляры конкретных классов.


 
evvcom ©   (2006-08-10 13:50) [20]

> [18] Kolan ©   (10.08.06 13:41)

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


 
Kolan ©   (2006-08-10 13:52) [21]

Ну это я так себе это понял. Мож и не верно.

Тут смотри:
Виртуальный конструктор Create класса TComponent
http://delphimaster.net/view/1-1154509872/


 
Kolan ©   (2006-08-10 14:07) [22]

Перечитал

> который в данном случае становится генофондом, а про генофонд,
>  надеюсь, уже все знают

Что становится генофондом?


 
evvcom ©   (2006-08-10 14:08) [23]

> [21] Kolan ©   (10.08.06 13:52)

Да там особо и смотреть нечего. Ты DevExpress (dxGrid, dxTreeList) по возможности посмотри и попробуй написать и зарегить свои классы столбцов. Вот там есть чему поучиться, настолько гибко написано. Да такое, наверняка, и в других продвинутых библиотеках найдешь.


 
evvcom ©   (2006-08-10 14:13) [24]

> [22] Kolan ©   (10.08.06 14:07)
> Что становится генофондом?

Код, библиотека, которые в общем-то уже предназначены для использования в прикладных целях.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2006.09.24;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.054 c
2-1157437863
worldmen
2006-09-05 10:31
2006.09.24
Программное изменение языков.


6-1146868280
KASioZ
2006-05-06 02:31
2006.09.24
Состояние сокета winsock


2-1157606833
WeeK
2006-09-07 09:27
2006.09.24
Нет курсора


2-1157308104
Koka
2006-09-03 22:28
2006.09.24
HELP!


2-1157364800
Ragazor
2006-09-04 14:13
2006.09.24
Как создать в Dll переменную TDataModule из DataModule1.pas





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский