QueryInterface транзитивна
Спецификация СОМ требует также, чтобы, если запрос QueryInterface
на интерфейс В удовлетворяется через интерфейсный указатель типа
A, а второй запрос QueryInterface на интерфейс C
удовлетворяется через указатель типа В, то запрос QueryInterface
на интерфейс C через исходный указатель типа A был бы
также успешным. Это означает, что если верно
QI(QI(A)->B)->C
то должно быть верным и
QI(A)->C
Это условие иллюстрируется рис. 4.3 и означает, что утверждение, приведенное
в нижеследующем коде, должно всегда быть верным:
void AssertTransitive(ICar *pCar)
{
if (pCar) {
IPlane *pPlane = 0;
// request intermediate type of interface
// запрос промежуточного типа интерфейса
HRESULT hr = pCar->QueryInterface(IID_IPlane, (void**)&pPlane);
if (SUCCEEDED(hr)) {
IBoat *pBoat1 = 0;
// request terminal type of interface
// запрос конечного типа интерфейса
hr = pPlane->QueryInterface(IID_IBoat, (void**)&pBoat1);
if (SUCCEEDED(hr)) {
IBoat *pBoat2 = 0;
// request terminal type through the original pointer
// запрос конечного типа через исходный указатель
hr = pCar->QueryInterface(IID_IBoat, (void**)&pBoat2);
// if the following assertion fails, pCar
// did not point to a valid СОМ object
// если следующее утверждение неверно, то pCar
// не указывал на корректный СОМ-объект
assert(SUCCEEDED(hr));
pBoat2->Release();
}
pBoat1->Release();
}
pPlane->Release();
}
}
Из транзитивности QueryInterface следует, что все интерфейсы,
которые выставляет объект, равноправны и не требуют, чтобы их вызывали
в какой-то определенной последовательности. Если бы это было не так, то
клиентам пришлось бы заботиться о том, какой указатель на объект использовать
для различных запросов QueryInterface. Из транзитивности и симметричности
QueryInterface следует, что любой интерфейсный указатель на объект
выдаст тот же самый ответ "да/нет" на любой запрос QueryInterface.
Единственная ситуация, не охватываемая транзитивностью и симметричностью,
это повторные запросы одного и того же интерфейса. Эта ситуация требует,
чтобы QueryInterface был и рефлективным.
QueryInterface рефлективна
Объекты имеют статический тип
Единственность и идентификация
QueryInterface и IUnknown
Множественные интерфейсы и имена методов
Динамическая композиция
Двоичная композиция
Включение
Где мы находимся?
|