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

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.017 c
1-31223
Alibaba
2003-06-27 16:29
2003.07.10
TSpeedButton


3-31145
Rel_
2003-06-18 16:39
2003.07.10
считывание данных из таблицы (.dbf)


14-31482
Mike B.
2003-06-24 14:46
2003.07.10
Суровые армейские будни


11-31164
battar
2002-10-21 20:26
2003.07.10
А какой нить репорт будет на основе КОЛ?


14-31480
pusrg
2003-06-20 13:14
2003.07.10
Киевское