Форум: "Основная";
Текущий архив: 2003.05.08;
Скачать: [xml.tar.bz2];
ВнизПередать поле объекта как var параметр в процедуру Найти похожие ветки
← →
Sergey Masloff (2003-04-25 21:54) [0]Пусть есть процедура:
MyProcedure(var AParam : Double);
Хочу передать в качестве AParam свойство объекта.
Так я конечно могу:
var Tmp : Double;
...............
MyProcedure(Tmp);
MyObject.SomeDoubleProperty := Tmp;
при этом появляются ненужные локальные переменные
Так я конечно тоже могу:
MyProcedure(Double(Pointer(@MyObject.SomeDoubleProperty)^));
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Но больно уж выглядит... не очень.
Еще варианты?
← →
default (2003-04-25 22:18) [1]Конкретней
← →
jack128 (2003-04-25 22:29) [2]
> Еще варианты?
Нет. Кстати объясни смысл второго варианта?
Такой пример у мя не работает(в смысле высота не меняется) :
procedure Proc(var i : integer);
begin
i := 100;
end;
procedure TForm1.Button1Click(Sender: TObject);
var s : string;
begin
Proc(integer(Pointer(@Self.height)^));
end;
← →
Palladin (2003-04-25 22:33) [3]нет
← →
Palladin (2003-04-25 22:41) [4]каким образом вы ребята свойства как параметры передаете?
← →
default (2003-04-25 22:49) [5]to jack128
твой код не сработал даже если бы "@Self.height" возвращал бы адрес переменной через которую работает св-во Height и Self тут не нужен тогда уж просто "@Height"
потому что ты в Proc педедаёшь не адрес а значение св-ва Height
но это всё не работает
← →
default (2003-04-25 23:00) [6]to jack128
хотя "@Height" действительно возвращает адрес переменной через которую работает св-во Height!Но высота не меняется по понятным причинам...мы изменяем лишь значение и это мы делаем напрямую минуя что-то типа SetHeight!
вот этот код тебя я уверен заинтересует!
procedure TForm1.Button1Click(Sender: TObject);
begin
Caption := IntToStr(Width);
Integer(Pointer(@Width)^) := 100;
Caption := Caption + " : " + IntToStr(Width);
Width := Width + 1
end;
Крюто...будем знать...
← →
jack128 (2003-04-25 23:03) [7]default © (25.04.03 22:49)
> Self тут не нужен
писать self или не писать здесь значения не имеет.
> тогда уж просто "@Height"
компилятор скажет "переменная требуется" и будет трижды прав -)
> procedure Proc( var i : integer);
← →
jack128 (2003-04-25 23:21) [8]в общем подведем итог
если свойство объявлено как
proprty MyProp : <MyType> read <MyField> ...
то @<MyObject>.MyProp возвращяет адрес поля Ffield совсеми вытекающими... Иначе компилятор показывает ошибку...
По моему сама возможность такой конструкции нарушает принципы ООП...
← →
Palladin (2003-04-25 23:38) [9]
> jack128 © (25.04.03 23:21)
иначе компилятор по идее должен возвратить адрес метода...
> По моему сама возможность такой конструкции нарушает принципы
> ООП...
а что еще делать, не копировать же тело метода или поля в отдельное адресное пространство... какое же дикое падение производительности получилось бы...
← →
default (2003-04-26 00:12) [10]" Self тут не нужен
писать self или не писать здесь значения не имеет."
смешной ты! поэтому я и говорю что писать не надо!
"компилятор скажет "переменная требуется" и будет трижды прав -)"
фигня, он это пишет когда св-во ReadOnly
← →
default (2003-04-26 00:21) [11]to Palladin
"а что еще делать, не копировать же тело метода или поля в отдельное адресное пространство... какое же дикое падение производительности получилось бы..."
ты о чём? какое АП...
просто надо было на уровне компилятора запретить применение оператора @ к свойствам и всё
да это вообщем и не важно особо
← →
Sergey Masloff (2003-04-26 05:18) [12]А так?
program Project2;
{$APPTYPE CONSOLE}
uses SysUtils;
type
TMyObj = class(TObject)
private
fProp : Integer;
procedure SetProp(AValue : Integer);
public
property Prop : Integer read fProp write SetProp;
end;
{ TMyObj }
procedure TMyObj.SetProp(AValue: Integer);
begin
fProp := AValue;
end;
procedure Proc(var AParam : Integer);
begin
AParam := 300;
end;
var
Obj : TMyObj;
begin
Obj := TMyObj.Create;
try
Proc(Integer(Pointer(@Obj.Prop)^));
WriteLn(Obj.Prop);
finally
Obj.Free();
end;
readln;
end.
тоже не компилируется?
← →
Anatoly Podgoretsky (2003-04-26 08:50) [13]Как прикажешь понимать тебя Абдулла
Pointer(@Obj.Prop)^));
Что это @FProp или @SetProp?
Такие вещи в пределах модуля делаются так: Proc(FProp), а за пределами модуля никак, поскольку в этом случае речь идет об обходе скрытия поля, о не санкционированном доступе к полю.
В этом случае положено делать так
Tmp := Prop;
Proc(Tmp);
Prop := Tmp;
Санкционированный метод доступа до скрытого поля. Ни какой надежды на обход нелегальными методами. На то оно и придумано - черный ящик, в идеале никаких видимых переменных (полей) у класса быть не должно, вся работа через свойства или методы. В классике через методы, поскольку нет свойств.
← →
Sergey Masloff (2003-04-26 09:02) [14]Anatoly Podgoretsky © (26.04.03 08:50)
>Как прикажешь понимать тебя Абдулла
>Pointer(@Obj.Prop)^));
>Что это @FProp или @SetProp?
Без разницы. Если @SetProp то в SetProp попадаем. Я проверил.
>В этом случае положено делать так
Вот это я и хотел спросить. В смысле как ПОЛОЖЕНО
Изначально суть проблемы такая: у меня есть есть функция вызова универсального справочника, и есть объект многие свойства которого через справочник устанавливаются. И мне хотелось избежать объявления на каждый вызов двух (два значения справочник возвращает) временных переменных. Возник вариант с указателями и разадресациями. Когда увидел во что это выливается то решил что все же наверное переменные - меньшее зло ;-)
В любом случае спасибо за ответ
← →
Anatoly Podgoretsky (2003-04-26 09:10) [15]У тебя не @SetProp а @Prop и как прикажешь это понимать, комплятору, что телепатией заниматься прикажешь?
А по уму Proc должен быть оформлен как функция, тогда
Prop := Proc(Prop);
← →
Sergey Masloff (2003-04-26 09:24) [16]Anatoly Podgoretsky © (26.04.03 09:10)
>У тебя не @SetProp а @Prop и как прикажешь это понимать, >комплятору, что телепатией заниматься прикажешь?
Я проверил, пишу @Prop если в объявлении свойства
write fProp то устанавливается значение fProp
если write SetProp то попадаем в процедуру SetProp. Я только вчера начал этот вопрос рассматривать и еще не понял как это происходит ;-)
то есть для
TMyObj = class(TObject)
private
fProp : Integer;
procedure SetProp(AValue : Integer);
public
property Prop : Integer read fProp write SetProp;
property Prop1 : Integer read fProp write fProp ;
end;
сработает и для
Proc(Integer(Pointer(@Obj.Prop)^));
и для
Proc(Integer(Pointer(@Obj.Prop1)^));
>А по уму Proc должен быть оформлен как функция,
Нельзя. Это и есть функция возвращает Boolean - состоялся выбор из справочника или нет. А возвращается два значения, одно системный идентификатор а второе его "декодированное" значение для отображения пользователю.
← →
Palladin (2003-04-26 11:00) [17]
> Sergey Masloff (26.04.03 09:24)
ты почему такой?
у тебя в обоих случаях для обеих свойств возвращается адрес переменной...
Obj.Prop - это обращение на чтение
вот такое выдаст у тебя ошибку сразу
TMyObj = class(TObject)
private
fProp : Integer;
procedure SetProp(AValue : Integer);
function GetProp:integer;
public
property Prop : Integer read fProp write fProp;
property Prop1 : Integer read GetProp write fProp;
end;
сработает и для
Proc(Integer(Pointer(@Obj.Prop)^));
но не сработает для
Proc(Integer(Pointer(@Obj.Prop1)^));
← →
Sergey Masloff (2003-04-26 11:41) [18]Palladin ©
>но не сработает для
>Proc(Integer(Pointer(@Obj.Prop1)^));
Ты пробовал? А чего пишешь. Говорю что сработает.
Скомпилируй и посмотри:
program Project2;
{$APPTYPE CONSOLE}
uses SysUtils;
type
TMyObj = class(TObject)
private
fProp : Integer;
procedure SetProp(AValue : Integer);
public
property Prop1 : Integer read fProp write SetProp;
end;
{ TMyObj }
procedure TMyObj.SetProp(AValue: Integer);
begin
fProp := AValue;
end;
procedure Proc(var AParam : Integer);
begin
AParam := 300;
Writeln("I""m here!");
end;
var
Obj : TMyObj;
begin
Obj := TMyObj.Create;
try
Proc(Integer(Pointer(@Obj.Prop1)^));
WriteLn(Obj.Prop1);
readln;
finally
Obj.Free();
end;
readln;
end.
← →
Sergey Masloff (2003-04-26 11:45) [19]Palladin © , Anatoly Podgoretsky ©
упс, сорри... Мужики, вспылил был неправ. Все торопливость подводит ;-)
← →
Sergey Masloff (2003-04-26 11:50) [20]Вобщем, несмотря на первоначально ошибочную посылку считаю что обсуждение полезное. По крайней мере все работает именно так как и должно. А то я, уж не знаю как, решил что попадаю внутьрь Set процедуры, и никак не мог понять как компилятор угадывает что ему делать ;-) видимо, переутомление так на бедный мозг повлияло...
Вобщем, для себя проблему решил. Всем спасибо!
← →
Sergey Masloff (2003-04-26 15:25) [21]Посмотрел в Debug Window -> CPU. Блин, лучше бы я сразу с этого начал ;-)
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.05.08;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.007 c