QueryInterface транзитивна
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 был и рефлективным.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Оптимизация QueryInterface
Оптимизация QueryInterface Фактически реализация QueryInterface, показанная ранее в этой главе, очень проста и легко может поддерживаться любым программистом, имеющим хоть некоторое представление о СОМ и C++. Тем не менее, многие среды и каркасы приложений поддерживают реализацию,
QueryInterface симметрична
QueryInterface симметрична Спецификация СОМ требует, чтобы, если запрос QueryInterface на интерфейс B удовлетворяется через интерфейсный указатель типа A, то запрос QueryInterface на интерфейс A того же самого объекта через результирующий интерфейсный указатель типа В всегда был успешным.
QueryInterface рефлективна
QueryInterface рефлективна Спецификация СОМ требует, чтобы запрос QueryInterface через интерфейсный указатель всегда достигал цели, если запрошенный тип соответствует типу указателя, с помощью которого произведен запрос. Это означает, что QI(A)->A всегда должен быть верным. Это
QueryInterface и IUnknown
QueryInterface и IUnknown Свойство рефлективности QueryInterface гарантирует, что любой интерфейсный указатель сможет удовлетворить запросы на IUnknown, поскольку все интерфейсные указатели неявно принадлежат к типу IUnknown. Спецификация СОМ имеет немного больше ограничений при описании