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

Вниз

Abstract процедура   Найти похожие ветки 

 
Евгений Р.   (2006-09-06 19:31) [0]

Как узнать переназначена ли Abstract процедура или нет?


 
Eraser ©   (2006-09-06 19:39) [1]

> [0] Евгений Р.   (06.09.06 19:31)

при попытке создать экземпляр абстрактного класса, компилятор ругнется.


 
Ega23 ©   (2006-09-06 19:42) [2]


> при попытке создать экземпляр абстрактного класса, компилятор
> ругнется.


warning выдаст. А вообще: не уверен - не стреляй. Назначай в базовом классе её как virtual с пустым обработчиком.


 
Евгений Р.   (2006-09-06 20:04) [3]

Не класс абстрактный, а метод (процедура).

   procedure CopyValue(OldValue: tCollectionItem;var NewValue: tCollectionItem); virtual; abstract;

хочется что то типа
 if assigned(CopyValue) then  .............
но приходится

 try
    CopyValue(OldValue,NewValue);
 except
.............
 end;
..........


 
default ©   (2006-09-06 20:08) [4]

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


 TMyClass = class
   procedure A1; virtual;
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TMyClass.A1;
begin
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 o: TMyClass;
 vmtofs: Integer;
begin
  o := TMyClass.Create;
  asm
    MOV vmtofs, VMTOFFSET TMyClass.A1
  end;
  if @TMyClass.A1 =  PPointer(PInteger(o)^+vmtofs)^
    then Caption := "метод не переопределён";
end;

но это всё забавы, в реальном коде подобной лабуды быть не должно


 
Eraser ©   (2006-09-06 20:08) [5]

> [3] Евгений Р.   (06.09.06 20:04)

абстрактным классом называется класс, у которого хотя бы один метод абстрактный.


 
Евгений Р.   (2006-09-06 20:35) [6]

Eraser ©  

Я может слаб в терминологии, но если "абстрактным классом называется класс, у которого хотя бы один метод абстрактный.", то как быть с Вашей фразой "при попытке создать экземпляр абстрактного класса, компилятор ругнется."?


 
Eraser ©   (2006-09-06 20:44) [7]

> [6] Евгений Р.   (06.09.06 20:35)

Ega23 в [2] уточнил.

варнинги игнорировать нельзя.


 
Anatoly Podgoretsky ©   (2006-09-06 20:48) [8]

Eraser ©   (06.09.06 20:08) [5]
Борланд называет это базовый класс, а абстрактным называл на заре ранней молодости


 
guav ©   (2006-09-06 20:50) [9]

Можно подменить AbstractErrorProc и не давать сработать стандартной обработке AbstractError.
(грязный хак, не для всех версий RTL)
unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   procedure FormCreate(Sender: TObject);
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
   procedure P; virtual; abstract;
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure AbstractError;
begin
 ShowMessage("Пойман вызов абстрактоного метода");
end;

procedure _AbstractErrorProc;
asm
 POP EAX
 CALL AbstractError;
 RET
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 System.AbstractErrorProc := _AbstractErrorProc;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 P;
end;


 
default ©   (2006-09-06 20:54) [10]

guav ©   (06.09.06 20:50) [9]
я тоже так хотел только не нашёл System.AbstractErrorProc


 
Eraser ©   (2006-09-06 20:56) [11]

> [8] Anatoly Podgoretsky ©   (06.09.06 20:48)


> [8] Anatoly Podgoretsky ©   (06.09.06 20:48)

пожалуй соглашусь с уточнением, т.к. в какой-то из последних версий появилась возможность явно указывать, что класс абстрактный, т.о. именно класс, объявленный с ключевым словом abstract считается плностью_абстрактным.

A class type declaration has the form
type
  className = class [abstract | sealed] (ancestorClass)
     memberList  
  end;
where className is any valid identifier, the sealed or abstract keyword is optional, (ancestorClass) is optional, and memberList declares members - that is, fields, methods, and properties - of the class. If you omit (ancestorClass), then the new class inherits directly from the predefined Borland.Delphi.System.TObject class. If you include (ancestorClass) and memberList is empty, you can omit end. A class type declaration can also include a list of interfaces implemented by the class; see Implementing Interfaces.

If a class is marked sealed, then it cannot be extended through inheritance. If a class is marked abstract, then it cannot be instantiated directly using the Create constructor. An entire class can be declared abstract even if it does not contain any abstract virtual methods. A class cannot be both abstract and sealed.


но это уже буквоедство, которое сути дела не меняет.


 
Anatoly Podgoretsky ©   (2006-09-06 21:11) [12]

Eraser ©   (06.09.06 20:56) [11]
Это в Д10


 
Евгений Р.   (2006-09-06 21:27) [13]

Так все же можно ли по ходу выполнения ИЗЯЩНО определить определить переопределена ли процедура базового класса или продолжает быть абстрактной без попытки ее вызова?

Если все же пытаться вызывать, то помоему изящней прибегнуть к обработке исключения.


 
Eraser ©   (2006-09-06 21:32) [14]

> [13] Евгений Р.   (06.09.06 21:27)

вообще то определять надо на стадии разработки.

но скорее всего можно и в рунтайм - залезть в VMT.. но это только догадки, на практике не пробовал.


 
guav ©   (2006-09-06 21:46) [15]

> Так все же можно ли по ходу выполнения ИЗЯЩНО определить
> определить переопределена ли процедура базового класса

Вряд ли.
Экзепляры абстрактных классов просто не должны создаваться.


 
Eraser ©   (2006-09-08 21:14) [16]

вот очень хорошая статья по теме, которая дает ответ на сабж и помогает понять объектную модель Делфи в целом.
http://www.rsdn.ru/article/Delphi/delphiabs.xml


 
Loginov Dmitry ©   (2006-09-08 21:20) [17]

> Как узнать переназначена ли Abstract процедура или нет?


Налетишь на абстрактный метод. Получишь exception. Сразу узнаешь. Зачем определять это программно? Что за задача такая возникла?


 
Ketmar ©   (2006-09-08 21:25) [18]

> [17] Loginov Dmitry ©   (08.09.06 21:20)
для начала -- компилятор не особо-то и молчать станет при попытке создания класса с нереализованными методами.


 
DiamondShark ©   (2006-09-08 21:32) [19]


> для начала -- компилятор не особо-то и молчать станет при
> попытке создания класса с нереализованными методами.

Компилятор может и не знать, экземпляр какого класса будет создаваться.


 
Eraser ©   (2006-09-08 21:51) [20]

> [17] Loginov Dmitry ©   (08.09.06 21:20)


> [18] Ketmar ©   (08.09.06 21:25)

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


 
Percent   (2006-09-08 22:55) [21]

Абстрактный метод обязан быть переопределен в первом же наследнике.
И к гадалке не ходи.
Все остальное - палата в дурдоме с разложенными граблями и выключенным светом. Для желающих вход всегда открыт.


 
Loginov Dmitry ©   (2006-09-09 09:23) [22]

> для начала -- компилятор не особо-то и молчать станет при
> попытке создания класса с нереализованными методами


Если абстрактные методы окажутся в секции private, то компилятор ругаться не особо-то и станет.


 
Ketmar ©   (2006-09-09 11:42) [23]

> [21] Percent   (08.09.06 22:55)
и совсем не обязательно именно в первом. факт в том, что не надо создавать (даже в мечтах) экземпляры классов, у которых есть неконкретизированные методы.

> [22] Loginov Dmitry ©   (09.09.06 09:23)
абстрактные методы в private -- это что-то шибко странное, скажу я вам.


 
iZEN ©   (2006-09-09 20:38) [24]

В Delphi узнать, что метод абстрактный, можно на этапе выполнения (ошибка вызова абстрактного метода - EAbstractError) или на этапе разработки с помощью иных средств интроспекции кода. Компилятор Delphi не  считает создание объекта класса с абстрактным методом за ошибку.

Действиельно, граблей будет разложено множество, если в иерархии классов множество классов с абстрактными методами. А если они ещё и не документированы или документация отсутствует, то это похоже на палату для буйных душевнобольных.


 
Loginov Dmitry ©   (2006-09-09 21:23) [25]

> Ketmar ©   (09.09.06 11:42) [23]
> абстрактные методы в private -- это что-то шибко странное,
> скажу я вам.


Спасибо! Это замечание позволило мне исправить оплошность в одном из моих проектов. Такие методы действительно следует размещать в секции protected.


 
iZEN ©   (2006-09-09 22:04) [26]


> Loginov Dmitry ©   (09.09.06 09:23) [22]
> Если абстрактные методы окажутся в секции private, то компилятор
> ругаться не особо-то и станет.

Ну тогда настоящие чудеса вас ждут. Ж)))


 
DiamondShark ©   (2006-09-09 22:18) [27]

А в чём проблемы с абстракными методами в private?


 
iZEN ©   (2006-09-09 22:25) [28]


> DiamondShark ©   (09.09.06 22:18) [27]
>
> А в чём проблемы с абстракными методами в private?

А вы уверены, что класс с абстракным private-методом оттестирован и никакой код ни при каких условиях его не вызывает? А если где в потомке будет вызван обычный переопределённый метод, который по некоему условию (так сложились звёзды) потребует вызвать код из предка, а тот в свою очередь, вызовет приватный абстрактный метод родного класса, исходя из этого условия? ж)


 
Ketmar ©   (2006-09-09 22:44) [29]

> [27] DiamondShark ©   (09.09.06 22:18)
а поясни мне, зачем они там? вообще-то private -- оно private для конкретного класса. по правилам (не берём Delphi %-) -- никто его больше видеть не должен. ну и как прикажете перекрывать интимные методы? тем более учитывая, что в private обычно живёт то, что жёстко завязано на конкретную реализацию? это значит -- пустить по ветру всю идею ООП. и приветствовать поцелуями геморрои.


 
Loginov Dmitry ©   (2006-09-09 23:35) [30]

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


 
Eraser ©   (2006-09-09 23:38) [31]

> [30] Loginov Dmitry ©   (09.09.06 23:35)

ругнется.


 
Плохиш ©   (2006-09-10 04:16) [32]

Интересный такой разговор ни о чём. И не лень кнопки топтать?


 
Loginov Dmitry ©   (2006-09-10 09:56) [33]

> Eraser ©   (09.09.06 23:38) [31]
>
> ругнется.


Мой D7 не ругается :)


 
Eraser ©   (2006-09-10 15:48) [34]

> [33] Loginov Dmitry ©   (10.09.06 09:56)

мой BDS2006 ругается :)

> [32] Плохиш ©   (10.09.06 04:16)
> Интересный такой разговор ни о чём.

ну не так уж и не о чем )


 
Gero ©   (2006-09-10 19:23) [35]

> ругнется.


> Мой D7 не ругается


> мой BDS2006 ругается

— Ругнется!
— Не ругнется!


 
Loginov Dmitry ©   (2006-09-11 00:20) [36]

BDS2005 тоже ругается. (а D7 - по прежднему - нет :-).
Ну хоть какое-то отличие в положительную есть в bds2005 от D7, а то все тормоза, да глюки (пользуюсь этой хренью только чисто в эксперементальных целях).


 
Eraser ©   (2006-09-11 01:31) [37]

> [36] Loginov Dmitry ©   (11.09.06 00:20)

насчет плевков в сторону Д2005 согласен, а вот Д2006 достойный продукт imho.



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

Форум: "Прочее";
Текущий архив: 2006.10.01;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.013 c
5-1140106590
misha_gr
2006-02-16 19:16
2006.10.01
Грамотное управление HintWindow


15-1157888428
Konstantin555
2006-09-10 15:40
2006.10.01
Чему равен интеграл dx/(1-x) ?


15-1157699105
hhhhh
2006-09-08 11:05
2006.10.01
Как будет грамотнее?


2-1157735163
Juri
2006-09-08 21:06
2006.10.01
Отправить E-Mail


15-1158048675
ПЛОВ
2006-09-12 12:11
2006.10.01
Вот тут возник такой вопрос





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский