Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Объектный процедурный тип [D6, WinXP]


postedman ©   (2008-12-13 17:24:00) 

Возник у меня тут такой вопрос. Скажем, есть у меня указатель на объектную функцию, скажем так:

type
 TMethod = function(const A, B : integer) : integer of object;

Есть объект:

type
 TFManager = class(TObject)
public
   { Public declarations }
   function Sum(const A,B : integer) : integer;

Тогда в программе я легко могу вызвать
Method : TMethod;
Manger : TFManager;
Method:=Manager.Sum;

Но предположим у меня есть еще не объектная, общая функция

function Add(const A,B : integer) : integer;

Как мне с помощью этого же самого указателя (Method) вызвать ее? Что и как нужно указателю присваивать?


postedman   (2008-12-13 20:47:00) [1]

Так оно работает, хз, понравится ли преподавателю.
Спасибо огромное, я уже просто не знал, к кому обратиться, а то преподавателей у нас по дельфи всего два. Один ведет лекции и ничего почти не знает с практической точки зрения, а второй ведет лабы и любит задать какой-нибудь вопрос, попросить что-нибудь сделать, причем не обязательно полезное или умное, а сделать только потому, что так сделать можно... %))

Спасибо огромное)


Servy   (2008-12-13 20:40:00) [2]

type
 TMethod = function(const A, B: Integer): Integer of object;

var
 Method : TMethod;

type
 TSum = function (const A, B: Integer): Integer;

function Add(const A, B: Integer) : Integer;
begin
 Result := A + B;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 System.TMethod(Method).Code := @Add;
 ShowMessage(IntToStr(
     TSum(System.TMethod(Method).Code)(2,2)));
end;


Видимо, это соответствует постановке задачи
> Но предположим у меня есть еще не объектная, общая функция


> Как мне с помощью этого же самого указателя (Method) вызвать
> ее?


Но на самом деле редкая глупость. Есть мнение, что либо:
1. Ты не правильно понял преподавателя
2. Преподаватель не адекватен


postedman   (2008-12-13 20:40:00) [3]

Sum с его помощью я вызыву так:
summa := method(2,2);

Тип TMethod - это мой тип, не стандартный, уж сорри, что так совпало имя.
Мне просто задали это сделать, и я нигде не могу найти как. Это тип - указатель на объект какого-то класса. В моем примере - указатель на Manager.Sum.

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

И не спрашивайте зачем делать все через такое место - это ОНИ хотят... %)


Servy   (2008-12-13 20:36:00) [4]

> Сорри, да, это мой собственный тип. Так как это сделать
> с моим типом?


Твой тип точно также представляет собой 8 байтовую структуру. И его можно привести у типу System.TMethod. Дальше, все сказанное остается справедливым.


postedman   (2008-12-13 20:33:00) [5]

В указателе на объектную функцию первые четыре байта отводятся на адрес подпрограммы, а вторые - на экземпляр объекта, как я помню. Получается мне нужно к ним по отдельности обратиться, и записать в первые 4 байта указатель на внешнюю, необъектную функцию, а во вторые четыре записать nil. Вот только как это сделать?


Servy   (2008-12-13 20:33:00) [6]

> Как мне с помощью этого же самого указателя (Method) вызвать
> ее?


А как ты с его помощью вызываешь Sum? Я не вижу способа вызвать его без приведения к нужному типу, например:

TNotifyEvent(Method)(MySender);

Если очень хочется, то можно запихнуть в TMethod укатазель на процедуру. Правда смысла в этом очень немного, почему бы не объявить обычный указатель вместо TMethod?

var
 Method : TMethod;

type
 TSum = function (const A, B: Integer): Integer;

function Add(const A, B: Integer) : Integer;
begin
 Result := A + B;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 Method.Code := @Add;
 ShowMessage(IntToStr(
     TSum(Method.Code)(2,2)));
end;


postedman   (2008-12-13 20:01:00) [7]

Сорри, да, это мой собственный тип. Так как это сделать с моим типом?


jack128_   (2008-12-13 19:45:00) [8]


> Пробовал уже так, сейчас вот снова попробовал - не работает:

а ты отучись от привычки - давать своим типам такие же названия, какие имею стандартные типы. Slym в своем ответе думал, TMethod - System.TMethod (или этот тип в sysUtils описал? не помню)


postedman   (2008-12-13 19:22:00) [9]

Пробовал уже так, сейчас вот снова попробовал - не работает:
Not enough actual parameters
Ругается на строчки:
Method.Code:=@Add;
Method.Data:=pointer(Manger);


Slym   (2008-12-13 18:44:00) [10]

postedman   (13.12.08 18:26) [2]
function Add( Self:TObject;const A,B : integer) : integer;

Method.Code:=@Add;
Method.Data:=pointer(Manger);


postedman   (2008-12-13 18:26:00) [11]

Мне, если честно, это нахрен не надо. Препод сказал "Так сделать можно, а как - ты должен мне ответить". Ничего никуда нельзя перемещать. Нужно присвоить объектному указателю ссылку именно на внешний, не объектный метод


Loginov Dmitry   (2008-12-13 18:00:00) [12]

> Как мне с помощью этого же самого указателя (Method) вызвать
> ее?


Непонятно, зачем это...
Но самое простое - добавить метод Add в тот же TFManager, и присваивать Method:=Manager.Add; (объект Manager при этом создавать не обязательно).


Наверх

Титульная страница Поиск, карта сайта Написать письмо