Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

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


Страницы:   1 2

Kiloper ©   (2006-08-09 11:34:00) 

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


evvcom   (2006-08-10 14:13:00) [1]

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

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


evvcom   (2006-08-10 14:08:00) [2]

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

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


Kolan   (2006-08-10 14:07:00) [3]

Перечитал

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

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


Kolan   (2006-08-10 13:52:00) [4]

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

Тут смотри:
Виртуальный конструктор Create класса TComponent
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1154509872&n=0


evvcom   (2006-08-10 13:50:00) [5]

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

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


Kolan   (2006-08-10 13:42:00) [6]


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

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


Kolan   (2006-08-10 13:41:00) [7]

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

> 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:33:00) [8]


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

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


evvcom   (2006-08-10 13:31:00) [9]

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

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


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


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

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


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


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


см. [8].

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

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


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


> Пусик ©   (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;


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

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

:)


evvcom   (2006-08-10 11:50:00) [13]


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

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


DrPass   (2006-08-10 10:19:00) [14]


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

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


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


> if FCanDestroy then inherited Free;

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


Anatoly Podgoretsky   (2006-08-10 09:54:00) [16]

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


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


> 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, а его замещение.


Loginov Dmitry   (2006-08-10 07:48:00) [18]

> В смысле?


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


Fay   (2006-08-10 03:36:00) [19]

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


Anatoly Podgoretsky   (2006-08-09 19:53:00) [20]

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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо