Снова IUnknown
IUnknown не имеет реализации по умолчанию, которая являлась
бы частью интерфейса системного вызова СОМ. Заголовочные файлы SDK не
содержат базовых классов, макросов или шаблонов, предусматривающих реализации
QueryInterface, AddRef и Release, которые должны
использоваться во всех программах на С или C++. Вместо этого Спецификация
СОМ (Component Object Model Specification) предоставляет очень
точные правила относительно допущений, которые клиенты и объекты могут
делать относительно этих трех методов. Этот набор правил формирует протокол
IUnknown и позволяет каждому разработчику объекта преобразовать
три указанных метода IUnknown во все, что имеет смысл для его
или ее объекта.
В главе 2 представлены фактические С++-реализации трех упомянутых методов,
но СОМ никоим образом не обязывает объекты использовать их. Все, что требует
СОМ, - это чтобы каждая реализация придерживалась базовых правил IUnknown.
Как это достигается, не имеет ни малейшего отношения к СОМ. Это делает
СОМ совершенно ненавязчивой, так как эта модель не требует, чтобы объект
делал системные вызовы, наследовал системным реализациям, а все, что от
него требуется, - это объявлять совместимые с СОМ указатели vptr.
На самом деле, как будет показано далее в этой главе, можно выставлять
наследующие IUnknown указатели vptr из классов, которые
не наследуют ни одному интерфейсу СОМ.
Правила IUnknown в совокупности определяют, что значит быть
объектом СОМ. Чтобы понять правила IUnknown, полезно начать с конкретного
примера. Рассмотрим следующую иерархию интерфейсов:
import "unknwn.idl";
[object, uuid(CD538340-A56D-11d0-8C2F-0080C73925BA)]
interface IVehicle : IUnknown {
HRESULT GetMaxSpeed([out, retval] long *pMax);
}
[object, uuid(CD53834l-A56D-11d0-8C2F-0080C73925BA)]
interface ICar : IVehicle {
HRESULT Brake(void);
}
[object, uuid(CD538342-A56D-11d0-8C2F-0080C73925BA)]
interface IPlane : IVehicle {
HRESULT TakeOff(void);
}
[object, uuid(CD538343-A56D-11d0-8C2F-0080C73925BA)]
interface IBoat : IVehicle {
HRESULT Sink(void);
}
СОМ использует стандартную технологию для визуального представления
объектов. Эта технология находится в рамках принципа СОМ отделения интерфейса
от реализации и не раскрывает никаких деталей реализации объекта, кроме
списка выставляемых им интерфейсов. Эта технология также визуально усиливает
многие из правил IUnknown. Рисунок 4.1 показывает стандартное
представление класса CarBoatPlane, который реализует все только
что определенные интерфейсы. Заметим, что единственный вывод, который
можно сделать из этого рисунка, таков: если не произойдет катастрофического
сбоя, объекты CarBoatPlane будут выставлять пять интерфейсов:
IBoat, IPlane, ICar, IVehicle и IUnknown.
Первое правило IUnknown, подлежащее исследованию, - это требование,
чтобы QueryInterface был симметричным, транзитивным и рефлексивным
(Symmetric/Transitive/Reflexive). Эти требования определяют отношения
между всеми интерфейсными указателями объекта и начинают определять понятие
идентификации (identity) объектов СОМ. Подобно всем правилам
IUnknown, эти требования должны исполняться всегда, за исключением
катастрофических сбоев, теми, кто хочет считаться действительным объектом
СОМ.
QueryInterface симметрична
QueryInterface транзитивна
QueryInterface рефлективна
Объекты имеют статический тип
Единственность и идентификация
QueryInterface и IUnknown
Множественные интерфейсы и имена методов
Динамическая композиция
Двоичная композиция
Включение
Где мы находимся?
|