Интерфейс не работает если тип - реализующий его класс.

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Ответить
Аватара пользователя
Deepthroat
постоялец
Сообщения: 144
Зарегистрирован: 06.09.2007 00:21:34
Откуда: Outer Heaven
Контактная информация:

Интерфейс не работает если тип - реализующий его класс.

Сообщение Deepthroat »

Есть класс, унаследованный от TInterfacedObject. TInterfacedObject реализует интерфейс IUnknown, что позволяет автоматически вызывать деструктор, как только объект перестает использоваться (при выходе из области видимости).

Код: Выделить всё

TApplication = Class(TInterfacedObject)
...
end;


В программе пишу:

Код: Выделить всё

var
    app: TApplication;

begin
    app := TApplication.Create();
end.


При этом вот деструктор не вызывается, его надо вызывать вручную, т.е. app.Free(). Ситуация не меняется, если типом объекта я указываю TInterfacedObject. Но дальше я делаю так:

Код: Выделить всё

var
    app: IUnknown;

begin
    app := TApplication.Create();
end.


И что же? Деструктор вызывается самостоятельно, как только объект покидает область видимости.

Собственно, вопрос. Так и должно быть или это косяк? Почему если класс реализует интерфейс, то его поведение становится ожидаемым только если я указываю типом сам интерфейс? Получается, если тип - не интерфейс, то и реализации интерфейса не происходит?
Odyssey
энтузиаст
Сообщения: 580
Зарегистрирован: 29.11.2007 16:32:24

Сообщение Odyssey »

Так должно быть, это не косяк, и в Delphi это работает также как в FPC. Автоматические подсчет ссылок и вызов деструктора работают только для переменных интерфейсного типа. Подсчет ссылок на переменные типа "класс" не ведется, какие бы интерфейсы этот класс не реализовывал. Управление созданием/уничтожением классов ведется вручную или классами-контейнерами.
Deepthroat писал(а):Получается, если тип - не интерфейс, то и реализации интерфейса не происходит?

Реализация интерфейса классом позволяет присвоить переменной типа "интерфейс" значение типа "класс, реализующий данный интерфейс", т.е.

Код: Выделить всё

var
    app: IUnknown;
begin
    app := TApplication.Create();
end.
Аватара пользователя
Deepthroat
постоялец
Сообщения: 144
Зарегистрирован: 06.09.2007 00:21:34
Откуда: Outer Heaven
Контактная информация:

Сообщение Deepthroat »

Спасибо за разъяснение.
Ответить