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

Вниз

Передать поле объекта как 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;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.02 c
14-23301
AVR
2003-04-21 20:14
2003.05.08
Delphi60 CLX. На вкладке Internet нет TXMLDocument.


1-23060
BBCHa
2003-04-25 16:25
2003.05.08
Нестандартная прорисовка скроллинга


3-22960
VlGrig1961
2003-04-16 11:48
2003.05.08
Oracle8 как уменьшить размер Tmp1orcl.ora


3-23044
Саня
2003-04-17 19:04
2003.05.08
Почему бухнут таблицы по весне?


9-22898
Ibrik
2002-08-31 17:03
2003.05.08
DelphiX