Форум: "Прочее";
Текущий архив: 2014.12.07;
Скачать: [xml.tar.bz2];
ВнизФункция возвращающая интерфейс Найти похожие ветки
← →
Дмитрий СС (2014-05-06 14:21) [0]Есть такой код:
program Project1;
{$APPTYPE CONSOLE}
type
TMyInterfacedObject = class(TInterfacedObject)
destructor Destroy; override;
end;
destructor TMyInterfacedObject.Destroy;
begin
Writeln("TMyInterfacedObject.Destroy");
inherited;
end;
function Foo: IInterface;
begin
Result := TMyInterfacedObject.Create;
end;
procedure Bar;
begin
Writeln("Bar 1");
Foo;
Writeln("Bar 2");
end;
begin
Bar;
Readln;
end.
Вывод следующий:
Bar 1
Bar 2
TMyInterfacedObject.Destroy
Вопрос следующий:
Можно ли полагаться на то, что интерфейс полученный подобным образом ВСЕГДА будет уничтожен при ВЫХОДЕ из функции?
← →
junglecat (2014-05-06 14:28) [1]в данном случае он уничтожен потому что при завершении процесса все объекты, ему принадлежащие, убиваются.
Но вообще-то правильно всегда делать Free
← →
Дмитрий СС (2014-05-06 14:35) [2]Слово "уничтожен", конечно, не к месту. Освобожден, конечно.
> junglecat (06.05.14 14:28) [1]
Для интерфейса нельзя вызвать Free. К тому же Destroy вызывается до Readln, т.е. тогда, когда процесс еще работает.
← →
Dimka Maslov © (2014-05-06 14:40) [3]Финализация интерфейса (вызов его метода _Release) выполняется автоматически при выходе из функции, независимо от причины выхода: нормального окончания, исключения или вызова Exit.
← →
Дмитрий СС (2014-05-06 14:40) [4]
> Финализация интерфейса (вызов его метода _Release) выполняется
> автоматически при выходе из функции
Т.е. ничего страшного в том, что он не присвоен никакой переменной?
← →
junglecat (2014-05-06 14:41) [5]> Destroy вызывается до Readln, т.е. тогда, когда процесс
> еще работает.
выход из области видимости Bar
← →
Dimka Maslov © (2014-05-06 14:50) [6]
> Т.е. ничего страшного в том, что он не присвоен никакой
> переменной?
он привоен неявно. Поскольку не существует "функции возвращающей интерфейс", на самом деле функция Foo есть procedure Foo(out Result: IInterface) под переменную выделяется память и указатель на неё передаётся через аргумент функции. При выходе из функции для него все равно вызовется _Release.
← →
Дмитрий СС (2014-05-06 14:52) [7]
> Dimka Maslov © (06.05.14 14:50) [6]
А почему вызов _Release происходит не сразу после вызова Foo, а только при выходе из процедуры Bar ?
← →
junglecat (2014-05-06 14:55) [8]> А почему вызов _Release происходит не сразу после вызова
> Foo
а какой был бы смысл в возвращаемом значении, которое умирает сразу после получения?
← →
icWasya © (2014-05-06 15:53) [9]В свете Dimka Maslov © (06.05.14 14:50) [6] процедуры bar, и Foo неявно превращаются
вfunction Foo(out FOO_RESULT: IInterface)
begin
FOO_RESULT:=TMyInterfacedObject.Create;
Exit( FOO_RESULT );
end;
procedure Bar;
var FOO_RESULT:IInterface = nil;
begin
try
Writeln("Bar 1");
Foo(FOO_RESULT);
Writeln("Bar 2");
finally
FOO_RESULT:=nil;// а только здесь вызывается FOO_RESULT._Release;
end;
end;
← →
Дмитрий СС (2014-05-06 15:55) [10]
> icWasya © (06.05.14 15:53) [9]
Ну это видно хотя бы из CPU, а это поведение документировано? Я в инете на этот счет не нашел ничего.
> а какой был бы смысл в возвращаемом значении, которое умирает
> сразу после получения?
Foo может делать кое какую работу и возвращать результат работы в виде интерфейса. А в Bar, к примеру, требвуется выполнить эту работу, а на результат плевать.
← →
jack128_ (2014-05-06 17:52) [11]Барри Келли говорил, что да, интерфейс будет уничтожен при выходе из функции, и это поведение не будет меняться. С другой стороны он уже уволился из Эмбаракадеро, так что кто знает, что будет дальше...
← →
Cobalt © (2014-05-06 18:34) [12]Дмитрий СС,
если хочешь управлять временем жизни интерфейса - управляй им!
← →
jack128_ (2014-05-06 19:13) [13]
> если хочешь управлять временем жизни интерфейса - управляй
> им!
Дима скорее всего спрашивает в контексте RAII for Delphi. Вещь приятная, хотя в плюсах конечно удобнее сделано.
← →
Dimka Maslov © (2014-05-06 19:21) [14]
> а это поведение документировано
Ищи по ключевому слову "Финализация"
← →
Дмитрий СС (2014-05-08 12:24) [15]Всем спасибо за обсуждение !
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2014.12.07;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.002 c