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

Вниз

Возвращение объекта из процедуры.   Найти похожие ветки 

 
Kolan ©   (2007-12-21 10:37) [0]

Здравствуйте, я хочу объявить такую процедуру:

procedure Proc(AParam: Integer; AnObject: TObject): Boolean;

Где в AnObject будет создан и возвращен объект.

Но я хочу объяснить пользователю процедуры, что это возвращаемый параметр.

Вопрос как это сделать? (Кроме справки ессно).

Может вопользоватся out? То есть:

procedure Proc(AParam: Integer; out AnObject: TObject): Boolean;
Не уверен что это вообще допустимо&#133


 
morgoth   (2007-12-21 10:38) [1]

не out, а var


 
jack128_   (2007-12-21 10:42) [2]


> не out, а var

почему??  


> Не уверен что это вообще допустимо…

вполне. Собсвенно у тя два варианта - либо vaк либо out параметр...


 
Ega23 ©   (2007-12-21 10:44) [3]

procedure Proc(AParam: Integer): TObject;

В случае успеха - возвращает объект. В случае неудачи - nil.
И не надо никаких изголений с var-параметром.


 
morgoth   (2007-12-21 10:44) [4]

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


 
morgoth   (2007-12-21 10:47) [5]

>>почему??  
хм, ошибочка, никогда out"ом не пользовался, даже не знал что такое есть, сорри

>>procedure Proc(AParam: Integer): TObject;
процедура возвращает объект?


 
Kolan ©   (2007-12-21 10:53) [6]

> В случае успеха — возвращает объект. В случае неудачи —
> nil.
> И не надо никаких изголений с var-параметром.

Понятно, но тогда не напишешь if Proc then. И не понятно что возвращает процедура.

Реально процедура такая:

function CheckDBVersion(MustBeDBVersion: IDBVersion;
     out ReallyFoundDBVersion: IDBVersion): Boolean;


 
Kolan ©   (2007-12-21 10:55) [7]

out меня устраивает, я его использую просто как напоминание и слово out имхо подходит гораздо лучьше. Я боюсь что так нельзя делать, что я че-нить попорчу&#133


 
Плохиш ©   (2007-12-21 10:57) [8]

Хм, вопрос был про объекты, в итоге оказались интерфейсы. Отсутствие знаний об отличии процедур от функций. Вывод: А не пора ли почитать чего-нибуть?


 
Kolan ©   (2007-12-21 10:59) [9]

> Хм, вопрос был про объекты, в итоге оказались интерфейсы

Разница в данном случае какакя?

Отсутствие знаний об отличии процедур от функций.
Мда, в сабже поспешил просто&#133


 
Kolan ©   (2007-12-21 11:00) [10]

То есть вопрос как указать пользователю, что
в ReallyFoundDBVersion не надо передавать созданый объект(поддерживающий интерфейс)?


 
{RASkov} ©   (2007-12-21 11:23) [11]

> [10] Kolan ©   (21.12.07 11:00)
> То есть вопрос как указать пользователю, что
> в ReallyFoundDBVersion не надо передавать созданый объект

function CheckDBVersion(MustBeDBVersion: IDBVersion;
    out ReallyFoundDBVersion: IDBVersion): Boolean;
begin
 if Assigned(ReallyFoundDBVersion) then raise Exception.Create("Юзверь, ты зачем мне созданный объект передал!?");
.....
end;

:о)
А может и не нужно его внутри создавать.... т.е. как обычно снаружи..... или вариант предложенный Ega23 [3] с функцией возвращающей объект

function Func(const AParam: Integer): IDBVersion;
....
procedure dfgdfg;
var idbv: IDBVersion;
begin
 idbv:=Func(100);
 if Assigned(idbv) then создался else что-то нехорошее случилось;
....
end;


 
Kolan ©   (2007-12-21 11:23) [12]

Ну дык как? Оставить мне out?


 
Kolan ©   (2007-12-21 11:25) [13]

> или вариант предложенный Ega23 [3] с функцией возвращающей
> объект

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


> if Assigned(ReallyFoundDBVersion) then raise Exception.Create("Юзверь,
> ты зачем мне созданный объект передал!?");

Так и думал сделать.


 
Kolan ©   (2007-12-21 11:26) [14]

Я просто out боюсь :), я им не пользовался никогда&#133 :)


 
Сергей М. ©   (2007-12-21 11:35) [15]


> Kolan ©   (21.12.07 11:26) [14]


> Я просто out боюсь


И зря.

Это практически тот же var, за исключением следующих ограничений/доп.возможностей:

1. out-параметр не доступен для чтения
2. При передаче типизированным out-параметром (например, интерфейсного типа) неинициализированной переменной она будет инициализирована, даже если в теле подпрограммы к этому параметру нет ни единого обращения по записи


 
Kolan ©   (2007-12-21 11:40) [16]

>
> 1. out-параметр не доступен для чтения

То есть я не смогу сделать:

S := ReallyFoundDBVersio.GetSmth?


> 2. При передаче типизированным out-параметром (например,
> интерфейсного типа) неинициализированной переменной она
> будет инициализирована, даже если в теле подпрограммы к
> этому параметру нет ни единого обращения по записи

То есть если передали nil, то на выходи всегда будет интерфейс(то есть не nil)?
Тогда не годится, мне надо иногда вернуть и nil в этот параметр.

Тогда использовать var?


 
Сергей М. ©   (2007-12-21 11:52) [17]


> То есть я не смогу сделать


Да, ты не сможешь в теле подпрограммы прочитать значение out-параметра - компилятор этого не допустит. Только записать в него сможешь.


> если передали nil, то на выходи всегда будет интерфейс(то
> есть не nil)?


Нет, конечно.

Если в теле п/п ты ни разу ничего не писал в этот параметр, то вызывающий код по возврату из п/п получит в этом параметре значение по умолчанию для конкретного типа данных.


> не годится, мне надо иногда вернуть и nil в этот параметр


Ну и возвращай, что мешает ?
Можешь и не возвращать явно - по идее компилятор сам запишет туда nil, поскольку параметр имеет объектный тип.


 
Kolan ©   (2007-12-21 11:57) [18]

> Да, ты не сможешь в теле подпрограммы прочитать значение
> out-параметра — компилятор этого не допустит. Только записать
> в него сможешь.

Ок, понял, это правильно, даже хорошо, мне и не надо&#133


> по умолчанию для конкретного типа данных.

То есть nil?

Все, остановился —  импользую out. Благодарю за обсуждение.


 
Сергей М. ©   (2007-12-21 12:03) [19]


> Kolan


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

Классический пример:

function SomeObject.GetSomeInterface(CLSID: TGUID; out Intf: IUnknown): Cardinal;

Вызывающий код готовит место под данные типа IUnknown, даже не удосуживаясь инициализировать их ни nil"ом ни каким-либо иным значением, и вызывает этот метод.

Тело метода в ходе выполнения возвращает в out-параметре запрошенный интерфейс или не возвращает его вообще, если по каким либо причинам сделать это невозможно, при этом код причины отказа метод возвращает через результат типа Cardinal.

Вызывающий код м.б. уверен в корректности интерфейсной ссылки, возвращенный out-параметром - она обязательно будет nil или корректной ссылкой на интерфейс. В случае nil вызывающий код может проанализировать результат вызова метода на предмет причин отказа.


 
Kolan ©   (2007-12-21 12:07) [20]

> Сергей М. ©   (21.12.07 12:03)

Благоарю за разъяснения, этого я и хотел, встало на место все. Буду теперь пользовать при надобности.


 
icWasya ©   (2007-12-21 12:30) [21]

>Сергей М. ©   (21.12.07 12:03) [19]
>Вызывающий код готовит место под данные типа IUnknown, даже не удосуживаясь инициализировать их ни nil"ом ни каким-либо иным значением, и вызывает этот метод.

Для интерфейсных типов компилятор всё-таки подставляет автоматическую инициализацию Nil-ом. И само присваивание в такую переменную - не просто пересылка 4-х байт.


 
Сергей М. ©   (2007-12-21 14:01) [22]


> icWasya ©   (21.12.07 12:30) [21]


Не суть как важно.



Страницы: 1 вся ветка

Текущий архив: 2008.01.20;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.017 c
15-1197847647
Почтальон
2007-12-17 02:27
2008.01.20
Как создать в Gmail.com папку?


2-1198380081
Шар
2007-12-23 06:21
2008.01.20
Как читать данные из потока в такое поле ?


15-1197402418
No_Dead
2007-12-11 22:46
2008.01.20
Атакуют что ли?!


15-1197781334
van
2007-12-16 08:02
2008.01.20
iis + apache


2-1197993742
IvanS
2007-12-18 19:02
2008.01.20
Интерфейсы