Текущий архив: 2005.08.14;
Скачать: CL | DM;
Вниз
Как идентифицировать объект по указателю на него ? Найти похожие ветки
← →
msguns © (2005-07-22 15:20) [0]На простом примере :
Есть процедура, которой передается указатель, куда надо положить некое число. Она должна определить, что "скрывается" под этим указателем. Если, например, это обект винкотрольный, то преобразовать число в строку и положить в св-во Text или Caption (в зависимомти от класса объекта), если строка - то просто положить туда. Если же Integer, то просто записать по этому адресу само число и т.д.
Благодарю всех участников.
← →
Джо © (2005-07-22 15:21) [1]В общем случае, имхо, никак.
← →
Digitman © (2005-07-22 15:35) [2]procedure (ptr: Pointer; Number: Integer);
begin
try
if TObject(ptr) is TSomeControl then
begin
TSomeControl(ptr).Text := IntToStr(Number);
Exit;
end;
except
end;
try
if TObject(ptr) is TSomeOtherControl then
begin
TSomeOtherControl(ptr).Text := IntToStr(Number);
Exit;
end;
except
end;
try
if строка then
просто положить туда (черт-те что подразумевается под "строка" и "просто положить туда")
except
end;
PInteger(ptr)^ := Number;
end;
← →
Lamer@fools.ua © (2005-07-22 15:44) [3]>Как идентифицировать объект по указателю на него ?
Либо пользоваться Variant"ами либо использовать технологии с поддержкой определения типа в ран-тайм (.NET, Java).
← →
Digitman © (2005-07-22 15:47) [4]
> Lamer@fools.ua © (22.07.05 15:44) [3]
теже фаберже, но вид сбоку
← →
msguns © (2005-07-22 15:49) [5]>Digitman © (22.07.05 15:35) [2]
Ну, до метода научного тыка я бы и сам догадался ;))
← →
Digitman © (2005-07-22 15:53) [6]
> msguns © (22.07.05 15:49) [5]
а тебя хак-методы интересуют ?)
← →
msguns © (2005-07-22 16:04) [7]>Digitman © (22.07.05 15:53) [6]
>а тебя хак-методы интересуют ?)
Меня интересует грамотно.
И красиво ;)
← →
Digitman © (2005-07-22 16:20) [8]
> msguns © (22.07.05 16:04) [7]
тогда грамотно же и излагай суть вопроса.
> передается указатель
типизированный ? упоминай тип.
нетипизированный ? см. [1]
← →
Джо © (2005-07-22 16:21) [9]
> [7] msguns © (22.07.05 16:04)
> Меня интересует грамотно.
> И красиво ;)
Для этого лучше всего грамотно подойти к проектированию алгоритма. Тогда и не будет нужды в хаках.
← →
evvcom © (2005-07-22 16:24) [10]Посмотри как работают функции New/Dispose с TypInfo.
← →
oldman © (2005-07-22 16:33) [11]
> Есть процедура, которой передается указатель
А заодно и тип переменной передать?
← →
Digitman © (2005-07-22 16:34) [12]
> evvcom © (22.07.05 16:24) [10]
не катит.
абсолютно.
← →
Digitman © (2005-07-22 16:37) [13]
> процедура, которой передается указатель
мол, нА тебе, процедура, адрес, по этому адресу что-то там лежит, что конкретно - разбирайся сама, это твои проблемы..
← →
Джо © (2005-07-22 16:39) [14]Еще раз о
> Меня интересует грамотно.
> И красиво ;)
Обращение к области памяти, не зная, что в ней лежит (или не лежит) - само по себе так "некрасиво", что о каких уж тут красивых решениях может идти речь?.. Сорри за занудство, но может обрисуешь задачу?
← →
evvcom © (2005-07-22 16:42) [15]
> не катит.
> абсолютно.
Ну так если вместе с указателем еще TypInfo передавать, должно ж прокатить? Хотя с тем же успехом можно и свой какой идентификатор передавать.
А вообще, конечно, задачи народ выдумывает странные. Я передал указатель, а ты попробуй угадай, что это?
← →
Digitman © (2005-07-22 16:45) [16]
> evvcom © (22.07.05 16:42) [15]
> если вместе с указателем еще TypInfo передавать, должно
> ж прокатить?
да мало ли чего должно !
автор, как я понял, не желает передавать ничего иного, кроме как нетип.указатель
← →
msguns © (2005-07-22 16:45) [17]>oldman © (22.07.05 16:33) [11]
>А заодно и тип переменной передать?
Поясняю предмет.procedure CalcAggregate(DataSet: TSQLDataSet; FieldList: TList; TargetValues: TList);
Процедура по переданному датасету строит запрос на вычисление агрегатов по полям, указанным в переданному же списку. Выполняет его и полученный результат должна положить по адресам, указанным в списке указателей, которые также передается. А вызывающая может дать ссылку на TEdit, TLabel, переменные типа Integer, double, string и т.д.
← →
Digitman © (2005-07-22 16:50) [18]
> А вызывающая может дать ссылку на
а вызывающая ДОЛЖНА дать список ВАРИАНТОВ, а не список абстрактных указателей !
вот тогда и вопрос сам собой рассосется)
← →
evvcom © (2005-07-22 16:52) [19]
> А вызывающая может дать ссылку на TEdit, TLabel, переменные
> типа Integer, double, string и т.д.
Ну так дай ссылку на record где присутствует информация о типе переменной.
← →
msguns © (2005-07-22 16:53) [20]>Digitman © (22.07.05 16:50) [18]
>а вызывающая ДОЛЖНА дать список ВАРИАНТОВ, а не список абстрактных указателей !
Можно примерчик. Как вызывающая сможет получить четыре числа:
одно в Эдите, второе в лабеле, третье как строку, а четвертое - как флоат. И как вызываемая со всех этой фигней разберется
← →
msguns © (2005-07-22 16:55) [21]>evvcom © (22.07.05 16:52) [19]
>Ну так дай ссылку на record где присутствует информация о типе переменной.
Ну какой же рекорд ? Процедура универсальная. К ней могут обращаться за получением как рдного агрегата, так и 100. И в абсолютно разные контролы или переменные.
← →
DiamondShark © (2005-07-22 16:55) [22]Не. Это фантастика.
Допустим, указатель на TEdit от TLabel отличить можно (хотя при выполнении кода, подобного [2] надо усиленно молиться). Но указатель на Integer отличить от указателя на Double -- унреально.
← →
DiamondShark © (2005-07-22 16:58) [23]Передавать массив обёрток, унаследованных от абстрактного класса -- и будет щасье.
← →
Digitman © (2005-07-22 17:02) [24]
> Как вызывающая сможет получить четыре числа:
> одно в Эдите, второе в лабеле,
да нет там, ни в Эдите ни в лабеле, никаких "чисел" !)
и вообще это проблемы вызывающего кода - где, как и какими средствами он изобразит рез-т работы вызываемого кода
вызываемый же код в данном случае может (и, вероятно, должен) вернуть вариантный массив, с которым вызывающий код уже волен делать все что угодно - хоть в лабеле хоть не в лабеле рисовать результаты ..
← →
reonid © (2005-07-22 17:02) [25]Можно сделать что-нибудь типа этого:
(Подобной техникой я пользовался, когда мне надо было реализовать обобщённые алгоритмы)
type
TAdapter = record
SetValue: procedure(Value: Integer) of object;
end;
implementation
{----}
procedure __SetInt(P: Pointer; Value: Integer);
begin
PInteger(P)^ := Value;
end;
procedure __SetStr(P: Pointer; Value: Integer);
begin
PString(P)^ := IntToStr(Value);
end;
procedure __SetWin(P: Pointer; Value: Integer);
begin
if GetPropInfo(TWinControl(P), "Caption") <> nil then
SetPropValue(TWinControl(P), "Caption", Value)
else if GetPropInfo(TWinControl(P), "Text") <> nil then
SetPropValue(TWinControl(P), "Text", Value)
end;
{-----}
function Adapter(var I: Integer): TAdapter; overload;
begin
TMethod(Result.SetValue).Data := @I;
TMethod(Result.SetValue).Code := @__SetInt;
end;
function Adapter(var S: string): TAdapter; overload;
begin
TMethod(Result.SetValue).Data := @S;
TMethod(Result.SetValue).Code := @__SetStr;
end;
function Adapter(Win: TWinControl): TAdapter; overload;
begin
TMethod(Result.SetValue).Data := Pointer(Win);
TMethod(Result.SetValue).Code := @__SetWin;
end;
{-----}
procedure Test(Adapters: array of TAdapter);
var i: Integer;
begin
for i := 0 to High(Adapters) do
Adapters[i].SetValue(6);
end;
procedure TForm1.FormCreate(Sender: TObject);
var I: Integer;
s: string;
begin
Test([Adapter(Self), Adapter(Panel1), Adapter(s), Adapter(I)]);
end;
← →
evvcom © (2005-07-22 17:03) [26]
> Ну какой же рекорд ? Процедура универсальная. К ней могут
> обращаться за получением как рдного агрегата, так и 100.
А что массивы уже отменили? У меня, например, так работают процедуры/классы. И никаких проблем.
← →
Digitman © (2005-07-22 17:12) [27]
> msguns © (22.07.05 16:45) [17]
и вообще - imho, крайне неразумно месить в функц-ти данной процедуры работу с СУБД и работу с виз.контролами
ну состряпай ты, коль приспичило, рекорд вида
TOutputKind = packed record
Kind: TKind; // 0 - TLabel, 1 - TEdit, 2 - PInteger, 3 - еще чего-то
ptr: Pointer; // поле Kind проинформирует, как с этим указателем обращаться
end;
и передай TList таких рекордов !
← →
Anatoly Podgoretsky © (2005-07-22 19:48) [28]msguns © (22.07.05 15:20)
В указаной постановке забудь, как сказали это фантастика.
← →
Mx © (2005-07-22 22:16) [29]Я вот тоже много мудрил с подобными фишками. По нетипизированному указателю ты такого не получишь. Остается либо [27], либо [23]. Для меня последний вариант оказался наиболее удобным. В конце концов от использования объектов ты мало что потеряешь, зато многие механизмы станут доступными.
← →
msguns © (2005-07-27 09:35) [30]>Digitman © (22.07.05 17:12) [27]
>и вообще - imho, крайне неразумно месить в функц-ти данной процедуры работу с СУБД и работу с виз.контролами
Я ничего и не месю ;) Библиотека, которую я пишу, содержит универсальные модули обработки датасетов, как правило, отображаемых (фильтрации, сортировки, поиски, печати, модификации, агрегаты и т.д. посредством диалогов с пользователем). Как получен датасет (т.е. собственно "работа с СУБД") этим модулям (точнее, процедурам и функциям в этих модулях) фиолетово.
Спасибо за критику и советы.
Отдельное мерси reonid © и Digitman ©
Страницы: 1 вся ветка
Текущий архив: 2005.08.14;
Скачать: CL | DM;
Память: 0.53 MB
Время: 0.011 c