Форум: "Начинающим";
Текущий архив: 2008.01.20;
Скачать: [xml.tar.bz2];
ВнизВозвращение объекта из процедуры. Найти похожие ветки
← →
Kolan © (2007-12-21 10:37) [0]Здравствуйте, я хочу объявить такую процедуру:
procedure Proc(AParam: Integer; AnObject: TObject): Boolean;
Где в AnObject будет создан и возвращен объект.
Но я хочу объяснить пользователю процедуры, что это возвращаемый параметр.
Вопрос как это сделать? (Кроме справки ессно).
Может вопользоватся out? То есть:procedure Proc(AParam: Integer; out AnObject: TObject): Boolean;
Не уверен что это вообще допустимо…
← →
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 имхо подходит гораздо лучьше. Я боюсь что так нельзя делать, что я че-нить попорчу…
← →
Плохиш © (2007-12-21 10:57) [8]Хм, вопрос был про объекты, в итоге оказались интерфейсы. Отсутствие знаний об отличии процедур от функций. Вывод: А не пора ли почитать чего-нибуть?
← →
Kolan © (2007-12-21 10:59) [9]> Хм, вопрос был про объекты, в итоге оказались интерфейсы
Разница в данном случае какакя?Отсутствие знаний об отличии процедур от функций.
Мда, в сабже поспешил просто…
← →
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 боюсь :), я им не пользовался никогда… :)
← →
Сергей М. © (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-параметра — компилятор этого не допустит. Только записать
> в него сможешь.
Ок, понял, это правильно, даже хорошо, мне и не надо…
> по умолчанию для конкретного типа данных.
То есть 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;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.042 c