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

Вниз

Как определить, является ли вызываемый метод абстрактным?   Найти похожие ветки 

 
Aleksandr   (2003-05-20 15:28) [0]

У базового объекта есть ряд абстрактных методов, по необходимости перекрываемых в потомках. Но некоторые потомки не используют эти методы, хотя они вызываются внутри используемых, и, соответственно, не переопределяют их, что при вызове приводит к Abstract Error. Есть ли более "культурный", чем try...except, способ узнать, что метод остался абстрактным?


 
AlexGreG   (2003-05-20 15:30) [1]

if Assigned(AbstractMethod) then AbstractMethod

или

if not AbstractMethod=nil then AbstractMethod

пробуй



 
Юрий Зотов   (2003-05-20 15:43) [2]

> Есть ли более "культурный", чем try...except, способ узнать,
> что метод остался абстрактным?

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


 
Aleksandr   (2003-05-20 15:50) [3]

Спасибо.


 
Skier   (2003-05-20 15:53) [4]

>Aleksandr © (20.05.03 15:28)
Можно сделать так :
(правда нужно будет код класса-предка править.)
Но как вариант...

TBasicClass = class(...)
protected
procedure SomeProc; virtual;
end; //TBasicClass

//..................

procedure TBasicClass.SomeProc;
begin
//do nothing...
end; //TBasicClass




 
Aleksandr   (2003-05-20 16:06) [5]

2 Юрий Зотов:

А теперь расскажите мне, как выглядит сообщение компилятора о том, что абстрактный метод не перекрыт? У меня отключено только одно сообщение - о депрекатных символах, но компилятор мне более ничего не пишет. Кроме того, если Вы невнимательно прочли мой вопрос, мне не надо найти неперекрытые методы, я их итак знаю, мне нужно корректно обработать их вызовы. Классический пример использования абстрактностей:

TBaseClass = class
protected
...
function DoEditRecord : boolean; virtual; abstract;
public
...
procedure EditRecord;
end;

procedure TBaseClass.EditRecord;
begin
GetPos;
if DoEditRecord then begin
RefreshData;
GoToPos
end
end;

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


 
Skier   (2003-05-20 16:18) [6]

>Aleksandr © (20.05.03 16:06)

> но далеко не каждая грида предусматривает редактирование,

"грида" (потомок), которая не предусматривает редактирование
должна реализовать метод DoEditRecord - сделать его пустым, например...


 
Anatoly Podgoretsky   (2003-05-20 16:22) [7]

Тут или обработает ошибку система, на первом по уровню обработчике except или если ты хочешь обрабатывать ошибки сам в этом месте то будь добр сделать защищенный блок, а то что ты хочешь сам, так на это намекает if DoEditRecord


 
Юрий Зотов   (2003-05-20 16:46) [8]

> Aleksandr © (20.05.03 16:06)

> А теперь расскажите мне, как выглядит сообщение компилятора о
> том, что абстрактный метод не перекрыт?

ОК, рассказываю. Оно выглядит вот так:
[Warning] Unit1.pas(27): Constructing instance of "TStrings" containing abstract methods


> У меня отключено только одно сообщение - о депрекатных
> символах, но компилятор мне более ничего не пишет.

У меня D5, и в опциях проекта есть только "Show Hints" и "Show Warnings". Поэтому - о каких депрекатных символах Вы говорите, я не знаю, но знаю, что чудес не бывает. Проверяйте настройки, что ж тут еще скажешь.


> Классический пример использования абстрактностей

Излишне. Полагаю, с сабжем я знаком далеко не понаслышке.


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

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




 
default   (2003-05-20 22:30) [9]

unit Unit1;

interface

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

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

TMyClass = class
procedure Proc; virtual; abstract;
procedure Proc2; virtual; abstract;
end;

var
Form1: TForm1;
Obj: TMyClass;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
Addr: Cardinal;
begin

Obj := TMyClass.Create;
asm
push eax
push edx
mov eax,Obj
mov edx,[eax]
mov eax,[edx + VMTOffset TMyClass.Proc2]
mov Addr,eax
pop edx
pop eax
end;
if Addr = $402918 then Caption := "TMyClass.Proc2 - абстрактный метод"

end;

end.

вот так можно в Delphi 6
в других версиях - не уверен


















 
vuk   (2003-05-20 22:53) [10]

Вообще говоря, если в каком-то случае требуется определить абстрактный метод или нет, то налицо ошибка проектирования связанная с неправильным пониманием назначения абстрактных методов. Абстрактные методы предназначены для того, чтобы быть обязательно перекрытыми в потомках, а не для того, чтобы быть заглушкой. Так что самый правильный метод решения здесь: Skier © (20.05.03 15:53)


 
Юрий Зотов   (2003-05-20 22:54) [11]

Можно, конечно, и через VMT. Только вот на эту строку:
Obj := TMyClass.Create;
компилятор все равно обругается.


 
Anatoly Podgoretsky   (2003-05-21 07:55) [12]

vuk © (20.05.03 22:53)
Асболютно согласен, из за этого получаются непрятные ошибки, хотя бы просто inherited, потом иначе будут непрятности.


 
default   (2003-05-21 21:40) [13]

Юрий Зотов © (20.05.03 22:54)
всмысле? ругается-то пусть, главно что работает?!
vuk © (20.05.03 22:53)
да это-то всем понятно
просто вопрос был - как определить абстрактный метод был


 
vuk   (2003-05-21 22:01) [14]

to default:
>просто вопрос был - как определить абстрактный метод был
По-хорошему - ничего не трогать. Пусть ругается, чем громче, тем лучше, т.к. применение таких классов - ошибка. К тому же, как я понимаю, есть какая-то библиотека классов собственного написания, где возникла проблема. Так может её лучше немного подкорректировать и избавиться от проблемы навсегда? Тем более, что решение-то простейшее.


 
default   (2003-05-21 23:40) [15]

vuk © (21.05.03 22:01)
бесспорно
я предложил просто как вариант


 
Юрий Зотов   (2003-05-21 23:53) [16]

> default © (21.05.03 21:40)

Немного не так. Вопрос был о КУЛЬТУРНОМ способе определения абстрактного метода. Так вот, САМЫЙ культурный способ - это обращать внимание на сообщения компилятора и писать код так, чтобы их не было. Ни одного. Без этого о какой-либо культуре программирования говорить просто не стоит.

А насчет "главно что работает" - это ОЧЕНЬ ошибочное мнение. Главное - чтоб не просто работало, а чтоб работало:
а). надежно;
б). не только сегодня, но и завтра, после каких-то изменений;
в). и чтоб позволяло легко эти изменения вносить.

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



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

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

Наверх




Память: 0.49 MB
Время: 0.007 c
1-2985
pirat
2003-05-20 22:10
2003.06.02
Подскажите пожалуйста, как повесить форму в отдельный поток?


14-3058
Dim!S
2003-05-15 07:14
2003.06.02
Исходники всегда с собой! :)


3-2822
gizar
2003-05-12 13:36
2003.06.02
Как работать с Lookup? ПОМОЖИТЕ!!!


14-3177
Ronin
2003-05-14 22:34
2003.06.02
Как убить процесс?


3-2756
Viktor
2003-05-12 05:33
2003.06.02
DBComboBox





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