Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.09.24;
Скачать: CL | DM;

Вниз

Чем отличается в классах 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://predskazanie-wunschpunsch.ru/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;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.08 c
15-1157308104
wp2
2006-09-03 22:28
2006.09.24
Решил попробовать использование прокси-сервера


15-1157449721
ПЛОВ
2006-09-05 13:48
2006.09.24
Подскажите пожалуйста где б найти такую вот информацию:


1-1155652862
sdf13
2006-08-15 18:41
2006.09.24
немецкий текст.


8-1141731106
Locke
2006-03-07 14:31
2006.09.24
Плеер и DLL библиотеки


15-1157058254
!_SM_!
2006-09-01 01:04
2006.09.24
BTN%Copy%1 BTN%Copy%2