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

Вниз

Перекрытие абстрактного метода   Найти похожие ветки 

 
Альф ©   (2004-02-03 16:18) [0]

Можно ли как-то определить - перекрыт ли абстрактный метод у наследника или нет, до вызова этого метода ???
Поясню на примере TStrings:

type
TMyStrings = class(TStrings)
public
procedure Clear(); override;
end;

procedure TMyStrings.Clear();
begin
ShowMessage("TMyStrings.Clear");
end;

procedure TForm1.Button1Click(Sender: TObject);
var
FStrings: TStrings;
begin
FStrings := TMyStrings.Create();
FStrings.Clear();
FStrings.Delete(0);
// ^^^ - вот тут получаем абстрактную ошибку, но так и должно быть
end;

Можно ли перед вызовом Delete(0) проверить - перекрыт ли метод - или нет ???

Существующий вариант решения с перехватом исключения меня не устраивает, т.е. такой

try
FStrings.Delete(0);
except
on EAbstractError // и далее
end;


Сложность в том что нужно убедиться в существовании перекрытого метода ДО вызова, примерно такое:

if ПерекрытЛиМетод(FStrings.Delete)
then FStrings.Delete(0);


 
Vuk ©   (2004-02-03 16:20) [1]

Может просто не делать метод абстрактным?


 
Альф ©   (2004-02-03 16:27) [2]

2Vuk © (03.02.04 16:20) [1]
Можно и не делать - просто пример был с TStrings.
Но всеже задача определения существования перекрытого метода остается :)


 
KSergey ©   (2004-02-03 16:27) [3]

А точно необходимо наследовать от TStrings? Вообще - что за класс и для чего предназначен? Вообще-то TStrings предполагает, что все его абстрактные методы перекроют.

А вообще на "королевстве" точно попадалать статейка про как определить. Где - не помню. Общая идея такова, что в таблице виртуюльных методов для абстрактного метода (а он всяко виртуальный) прописан нолик (nil по-дельфийски).
Видмо надо просто почитать какие-либо статейки про организацию виртуальных таблиц дельфийских. (вроде та статья посвящалась вызову метода "деда", а не "родителя"; во всяком случае работа с виртуальными таблицами там точно обсуждалась).


 
KSergey ©   (2004-02-03 16:29) [4]

В дополнение:

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


 
Игорь Шевченко ©   (2004-02-03 16:32) [5]

В журнале RSDN была статья на эту тему, номера не помню, но наверху есть ссылка.


 
VMcL ©   (2004-02-03 17:00) [6]

>>KSergey © (03.02.04 16:27) [3]

Не nil, а адрес проц. _AbstractError().


 
KSergey ©   (2004-02-03 17:03) [7]

> [6] VMcL © (03.02.04 17:00)
> >>KSergey © (03.02.04 16:27) [3]
>
> Не nil, а адрес проц. _AbstractError().

Да?
Впрочем, настаивать не буду. Мне запомнилось что-то про nil, вполне вероятно, что ошибаюсь (или автор статейки пидманул ;)


 
VMcL ©   (2004-02-03 17:05) [8]

>>KSergey © (03.02.04 17:03) [7]

Если бы был nil, то выскакивал бы AV, а не Abstract error.


 
KSergey ©   (2004-02-03 17:09) [9]

Ну почему, можно предположить, что штатный "прошаривальщик" виртуальных таблиц просто натыкаясь на nil вызывает обращение к _AbstractError() ;)
Впрочем, это лишь моя фантазия, как на самом деле - я не знаю.
Кинулся сейчас было в исходники - но это же думать надо... ;)


 
Skier ©   (2004-02-03 17:33) [10]

RSDN 02.2002 "Обработка абстрактных методов в Delphi"


 
jack128 ©   (2004-02-03 17:37) [11]

http://rsdn.ru/article/Delphi/delphiabs.xml

Но вообще мне не понятно зачем это нужно.
> Существующий вариант решения с перехватом исключения меня
> не устраивает, т.е. такой
>
> try
> FStrings.Delete(0);
> except
> on EAbstractError // и далее
> end;
Чем конкретно тя этот вариант не устраивает?


 
Тимохов ©   (2004-02-03 17:40) [12]

Не устараивает он его потому как нужно определить до вызова.
Вообще, нечего насиловать дельфи. ИМХО, конечно, но если возникают такие потребности, то что-то не так в архитектуре программы... Повторюсь, что это имхо.


 
Vuk ©   (2004-02-03 17:46) [13]

to Тимохов:
>если возникают такие потребности, то что-то не так в архитектуре
>программы...
Во-во. Ибо нефиг вообще классы с неперекрытыми абстрактными методами создавать.


 
jack128 ©   (2004-02-03 17:58) [14]


> Не устараивает он его потому как нужно определить до вызова.
Это я понял. Я не понял ЗАЧЕМ ему нужно определить абстрактность метода до вызова этого метода.


 
Mystic ©   (2004-02-03 17:59) [15]

Имхо, ошибка проектирования. Такой задачи возникать не должно.


 
WebErr ©   (2004-02-03 18:42) [16]

BeginUpdate и EndUpdate обычно вызываются автоматически, но в твоём случае это надо делать ручками! Между ними порть хоть весь TString, они обеспечат правильное выделение памяти под процесс. (Я думал это все знают.) Обязательно используй try-finally. Исходник не дам - думать в-лом. :)


 
Тимохов ©   (2004-02-03 19:29) [17]


> jack128 © (03.02.04 17:58) [14]
>
> > Не устараивает он его потому как нужно определить до вызова.
> Это я понял. Я не понял ЗАЧЕМ ему нужно определить абстрактность
> метода до вызова этого метода.


Думаю он сам не до конца сформулировал для себя, зачем ему это...


 
Юрий Федоров ©   (2004-02-03 21:35) [18]

Я бы не утверждал так категорично, что абстрактные методы должны быть перекрыты всегда, ситуаци бывают разные, главное - понимать, что делаешь

TAbstractClass = class
protected
procedure AbstractPtr(); virtual; abstract;
end;

PSinglePointerArray = ^TSinglePointerArray;
TSinglePointerArray = array[0..0] of Pointer;

...
var Vmt : PSinglePointerArray;
byte_offset: longword;
...
//Мы в методе этого класса
Vmt := pointer(ClassType);
asm
mov byte_offset, vmtoffset <тут ИмяКласса.ИмяМетода>
end;
if pointer(pointer(TAbstractClass)^) = Vmt^[byte_offset shr 2] then
//Метод абстрактный

Вроде что-то типа того :-)


 
Альф ©   (2004-02-04 10:02) [19]

Спасибо всем кто откликнулся.
Очень помогла эта статья на RSDN - Обработка абстрактных методов в Delphi



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

Текущий архив: 2004.02.13;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.04 c
1-38924
Владимир В.
2004-02-04 12:00
2004.02.13
Эмуляция нажатия клавиши в активное окно


3-38724
Igoryok
2004-01-21 22:38
2004.02.13
Interface Seeka в АДО - Jet


3-38713
Вопрошающий
2004-01-22 12:56
2004.02.13
F1Book - проблема с кириллическими шрифтами


9-38661
Sacred
2003-07-31 20:54
2004.02.13
Угол обзора камеры


14-39030
vopros
2004-01-26 12:44
2004.02.13
Есть плазменный телевизор есть компьютер