Форум: "Прочее";
Текущий архив: 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.015 c