![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Возвращение объекта из процедуры.
Kolan © (2007-12-21 10:37:00)Здравствуйте, я хочу объявить такую процедуру:
procedure Proc(AParam: Integer; AnObject: TObject): Boolean;
Где в AnObject будет создан и возвращен объект.
Но я хочу объяснить пользователю процедуры, что это возвращаемый параметр.
Вопрос как это сделать? (Кроме справки ессно).
Может вопользоватся out? То есть:
procedure Proc(AParam: Integer; out AnObject: TObject): Boolean;
Не уверен что это вообще допустимо
Сергей М. (2007-12-21 14:01:00) [1]
> icWasya © (21.12.07 12:30) [21]
Не суть как важно.
icWasya (2007-12-21 12:30:00) [2]>Сергей М. © (21.12.07 12:03) [19]
>Вызывающий код готовит место под данные типа IUnknown, даже не удосуживаясь инициализировать их ни nil'ом ни каким-либо иным значением, и вызывает этот метод.
Для интерфейсных типов компилятор всё-таки подставляет автоматическую инициализацию Nil-ом. И само присваивание в такую переменную - не просто пересылка 4-х байт.
Kolan (2007-12-21 12:07:00) [3]> Сергей М. © (21.12.07 12:03)
Благоарю за разъяснения, этого я и хотел, встало на место все. Буду теперь пользовать при надобности.
Сергей М. (2007-12-21 12:03:00) [4]
> Kolan
out вообще оч удобен при работе с объектными и интерфейсными типами, когда вызывающий код ожидает от вызываемого обязательнуюинициализацию данных, переданных в кач-ве этого параметра.
Классический пример:
function SomeObject.GetSomeInterface(CLSID: TGUID; out Intf: IUnknown): Cardinal;
Вызывающий код готовит место под данные типа IUnknown, даже не удосуживаясь инициализировать их ни nil'ом ни каким-либо иным значением, и вызывает этот метод.
Тело метода в ходе выполнения возвращает в out-параметре запрошенный интерфейс или не возвращает его вообще, если по каким либо причинам сделать это невозможно, при этом код причины отказа метод возвращает через результат типа Cardinal.
Вызывающий код м.б. уверен в корректности интерфейсной ссылки, возвращенный out-параметром - она обязательнобудет nil или корректной ссылкой на интерфейс. В случае nil вызывающий код может проанализировать результат вызова метода на предмет причин отказа.
Kolan (2007-12-21 11:57:00) [5]> Да, ты не сможешь в теле подпрограммы прочитать значение
> out-параметра компилятор этого не допустит. Только записать
> в него сможешь.
Ок, понял, это правильно, даже хорошо, мне и не надо
> по умолчанию для конкретного типа данных.
То есть nil?
Все, остановился импользую out. Благодарю за обсуждение.
Сергей М. (2007-12-21 11:52:00) [6]
> То есть я не смогу сделать
Да, ты не сможешь в теле подпрограммы прочитать значение out-параметра - компилятор этого не допустит. Только записать в него сможешь.
> если передали nil, то на выходи всегда будет интерфейс(то
> есть не nil)?
Нет, конечно.
Если в теле п/п ты ни разу ничего не писал в этот параметр, то вызывающий код по возврату из п/п получит в этом параметре значение по умолчанию для конкретного типа данных.
> не годится, мне надо иногда вернуть и nil в этот параметр
Ну и возвращай, что мешает ?
Можешь и не возвращать явно- по идее компилятор сам запишет туда nil, поскольку параметр имеет объектный тип.
Kolan (2007-12-21 11:40:00) [7]>
> 1. out-параметр не доступен для чтения
То есть я не смогу сделать:
S := ReallyFoundDBVersio.GetSmth?
> 2. При передаче типизированным out-параметром (например,
> интерфейсного типа) неинициализированной переменной она
> будет инициализирована, даже если в теле подпрограммы к
> этому параметру нет ни единого обращения по записи
То есть если передали nil, то на выходи всегда будет интерфейс(то есть не nil)?
Тогда не годится, мне надо иногда вернуть и nil в этот параметр.
Тогда использовать var?
Сергей М. (2007-12-21 11:35:00) [8]
> Kolan © (21.12.07 11:26) [14]
> Я просто out боюсь
И зря.
Это практически тот же var, за исключением следующих ограничений/доп.возможностей:
1. out-параметр не доступен для чтения
2. При передаче типизированным out-параметром (например, интерфейсного типа) неинициализированной переменной она будет инициализирована, даже если в теле подпрограммы к этому параметру нет ни единого обращения по записи
Kolan (2007-12-21 11:26:00) [9]Я просто out боюсь :), я им не пользовался никогда :)
Kolan (2007-12-21 11:25:00) [10]> или вариант предложенный Ega23 [3] с функцией возвращающей
> объект
Нет мне надо объяснить что будет возвращено, поэтому ф-ция не канает.
> if Assigned(ReallyFoundDBVersion) then raise Exception.Create('Юзверь,
> ты зачем мне созданный объект передал!?');
Так и думал сделать.
Kolan (2007-12-21 11:23:00) [11]Ну дык как? Оставить мне out?
{RASkov} (2007-12-21 11:23:00) [12]> [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:00:00) [13]То есть вопрос как указать пользователю, что
в ReallyFoundDBVersion не надо передавать созданый объект(поддерживающий интерфейс)?
Kolan (2007-12-21 10:59:00) [14]> Хм, вопрос был про объекты, в итоге оказались интерфейсы
Разница в данном случае какакя?
Отсутствие знаний об отличии процедур от функций.
Мда, в сабже поспешил просто
Плохиш (2007-12-21 10:57:00) [15]Хм, вопрос был про объекты, в итоге оказались интерфейсы. Отсутствие знаний об отличии процедур от функций. Вывод: А не пора ли почитать чего-нибуть?
Kolan (2007-12-21 10:55:00) [16]out меня устраивает, я его использую просто как напоминание и слово out имхо подходит гораздо лучьше. Я боюсь что так нельзя делать, что я че-нить попорчу
Kolan (2007-12-21 10:53:00) [17]> В случае успеха возвращает объект. В случае неудачи
> nil.
> И не надо никаких изголений с var-параметром.
Понятно, но тогда не напишешьif Proc then. И не понятно что возвращает процедура.
Реально процедура такая:
function CheckDBVersion(MustBeDBVersion: IDBVersion;
out ReallyFoundDBVersion: IDBVersion): Boolean;
morgoth (2007-12-21 10:47:00) [18]>>почему??
хм, ошибочка, никогда out'ом не пользовался, даже не знал что такое есть, сорри
>>procedure Proc(AParam: Integer): TObject;
процедура возвращает объект?
morgoth (2007-12-21 10:44:00) [19]хотя если объект создается вне процедуры, можно и без var
Если процедурой будет пользоваться программист, то он, я думаю, сам разберется...
Ega23 (2007-12-21 10:44:00) [20]
procedure Proc(AParam: Integer): TObject;
В случае успеха - возвращает объект. В случае неудачи - nil.
И не надо никаких изголений с var-параметром.