Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
14-23355
Andrey V.
2003-04-17 13:25
2003.05.08
Access violation


6-23279
Ocean
2003-03-11 15:05
2003.05.08
Откуда записали файл в мой общий каталог?


9-22905
Pavel_s
2002-12-06 16:07
2003.05.08
Вопрос по GLScene


3-22980
iStat
2003-04-17 06:33
2003.05.08
Помогите разобраться с Locate


1-23094
KA-87
2003-04-25 18:51
2003.05.08
Как из трея можно показывать советы? Как в ХР...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский