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

Вниз

inherited inherited;   Найти похожие ветки 

 
Um   (2003-06-25 06:44) [0]

Как можно вызвать inherited не у родителя а у дедушки.
Для примера
Задача такая: есть неплохой визуальный сторонний компонент.
Он наследован от Tcustomgrid,
в нем полностью переопределены MouseDown, KeyDown и т.д.
И ведет он себя не так как хотелось.
Надо чтобы управление было как в Tcustomgrid.
Как можно в MouseDown, KeyDown вернуться к Tcustomgrid?


 
ЮЮ   (2003-06-25 08:11) [1]

1) Опять переопределить, поместив туда снова "дедушкин" код
2) закомментировать "отцовское" переопределение


 
Um   (2003-06-25 14:19) [2]

1)
в "дедушкином" коде - вызывается inherited "прадедушки"
если переопределить то inherited будет "родителя"
2)
>закомментировать "отцовское" переопределение
в смысле исходним поправить - не выход, и не всегда возможно!
должен же быть способ вызвать виртуальный метод у нужного класса
типа TcustomGrid(mygrid).mousedown(...) причем mygrid другого типа
в таблице виртуальных методов есть адресса всех inherited методов, как найти адрес дедушки?


 
Smithson   (2003-06-25 14:50) [3]

Короче, Склифософкий!

есть метод OnMouseOver, перекрытый у твоего класса. Ты знаешь, что инетерсующий тебя класс есть наследник класса TCustomGrid. Тогда пишешь наследник от интересующего тебя класса, у него перекрываешь метод OnMouseOver и в этом методе пишешь TCustomGrid.OnMouseOver.

Не запутался?


 
uw   (2003-06-25 16:27) [4]

>Um (25.06.03 14:19)
>в таблице виртуальных методов есть адресса всех inherited методов, как найти адрес дедушки?

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

Но и TCustomGrid.OnMouseOver тоже не получится, это не BP. Все это неприятный прокол Delphi, imho.


 
VMcL   (2003-06-25 17:02) [5]

>uw © (25.06.03 16:27)
>не знает VMT ничего о дедовых методах

Знает, в VMT есть ссылка на VMT родительского класса.


 
VMcL   (2003-06-25 17:19) [6]

Привожу пример:

unit Unit1;

interface

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

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
end;

TGrandfather = class
procedure Test; virtual;
end;

TFather = class(TGrandfather)
procedure Test; override;
end;

TSon = class(TFather)
procedure Test; override;
procedure CallGrandTest;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

// AMethod - pointer to the method of such type: procedure XXX();
procedure CallMethod(const AObject, AMethod: Pointer); register;
asm
call edx
end;

{ TGrandfather }

procedure TGrandfather.Test;
begin
ShowMessage("Grandfather");
end;

{ TFather }

procedure TFather.Test;
begin
inherited;
ShowMessage("Father");
end;

{ TSon }

procedure TSon.CallGrandTest;
begin
CallMethod(Self, @TGrandfather.Test);
end;

procedure TSon.Test;
begin
ShowMessage("Son");
end;

procedure TForm1.FormCreate(Sender: TObject);
var
A: TSon;
begin
A := TSon.Create;
with A do
try
Test;
CallGrandTest;
finally
FreeAndNil(A);
end;
PostQuitMessage(0);
end;

end.


 
reonid   (2003-06-25 17:32) [7]

type
TMouseDownProc = procedure (Button: TMouseButton;
Shift: TShiftState; X, Y: Integer) of object;

THackCustomGrid = class(TCustomGrid);
// метод MouseDown - protected

procedure TYourGrid.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
var
md: TMouseDownProc;
begin
// вызов непосредственно метода TCustomGrid.MouseDown
// для данного экземпляра

TMethod(md).Code := @THackCustomGrid.MouseDown;
TMethod(md).Data := Self;

md(Button, Shift, X, Y);

//...
end;


 
VMcL   (2003-06-25 17:47) [8]

>reonid © (25.06.03 17:32)

Твой способ даже покрасивее :)


 
Gamar   (2003-06-25 17:56) [9]

Да нельзя делать такие вещи. Это нарушает принцип наследование. Пишите наследника дедушки, а не его потомка.


 
reonid   (2003-06-25 18:06) [10]

>Gamar © (25.06.03 17:56)
В старом турбопаскале, равно как и в современных Сях,
выполнение метода дедушки - вполне законная операция.
Иногда бывает полезна, хотя злоупотреблять не стоит.

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


 
VMcL   (2003-06-25 18:06) [11]

>Gamar © (25.06.03 17:56)
>Да нельзя делать такие вещи.

Если бы было нельзя делать такие вещи, то код VMcL © (25.06.03 17:19) и код reonid © (25.06.03 17:32) не работали бы.


 
uw   (2003-06-25 19:38) [12]

>VMcL © (25.06.03 17:19)
>reonid © (25.06.03 17:32)

Спасибо. Для меня было откровением, что синтаксис @TGrandfather.Test возможен. Но адрес все же берется не из VMT, а вычисляется компилятором точно так же, как и при inherited.


 
Gamar   (2003-06-25 19:43) [13]

> VMcL

Вероятно, их код не стоит считать верхом совершенства...


 
Serginio   (2003-06-25 20:05) [14]

Согласен с VMcL,reonid это самый простой и естественный способ.
Не согласен с Gamar так как на самом деле любой вызов метода объекта работает аналогично TMethod.


 
Um   (2003-06-26 06:47) [15]

>VMcL
>reonid
Я когда прочитал - от радости на стуле подпрыгнул
SQL.ru - слабаки
delphimaster.ru - рулёзззз




 
Um   (2003-06-26 07:28) [16]

Забыл, VMcL, Reonid, - большое спасибо!
>reonid
То-что доктор прописал - клёво!



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

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

Наверх




Память: 0.48 MB
Время: 0.007 c
1-31310
Holy
2003-06-26 18:10
2003.07.10
Delphi vs DivX


3-31136
ZDN
2003-06-18 09:23
2003.07.10
MSSQL, Oracle & DB2


1-31250
ViJen
2003-06-26 10:55
2003.07.10
Округление


7-31526
onezero
2003-04-27 14:21
2003.07.10
Как изменить системное время программно? Помогите!!!


14-31452
sapsi
2003-06-23 14:03
2003.07.10
Выплата пенсии





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