-. - , , . . CoGetClassObject , . CoCreateInstanceEx , a CoGetInstanceFromFile , . ÷ ÷ , ÷ MkParseDisplayName ÷ .
class object {
public:
template <class T> virtual
T * dynamic_cast(const type_info& t = typeid(T) )
};
Аноним, 1995
2 IUnknown ÷. , ÷ . , ø , ÷ . - QueryInterface ( ) - ++- dynamic_cast, .
, ÷ QueryInterface , ÷ , ÷ ÷ this , ø . ÷ ÷ , , C++ dynamic_cast .
QueryInterface , IUnknown ÷ ÷ ø , ÷ . , , .
Unknown
QueryInterface ÷
QueryInterface
QueryInterface
÷
QueryInterface 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 B ÷ A , QueryInterface A ÷ ø. ÷, ÷
QI(A)->B
QI(QI(A)->B)->A
, . 4.2, , ÷ , ÷ , :
void AssertSymmetric(ICar *pCar)
{
if (pCar) {
IPlane *pPlane = 0;
// request a second type of interface
// запрашиваем второй тип интерфейса
HRESULT hr = pCar->QueryInterface(IID_IPlane, (void**)&pPlane);
if (SUCCEEDED(hr)) {
ICar *pCar2 = 0;
// request original type of interface
// запрашиваем исходный тип интерфейса
hr = pPlane->QueryInterface(IID_ICar, (void**)&pCar2);
// if the following assertion fails, pCar
// did not point to a valid СОМ object
// если следующее утверждение не будет правильным,
// то pCar не укажет на правильный СОМ-объект
assert(SUCCEEDED(hr));
pCar2->Release();
}
pPlane->Release();
}
}
÷ 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 .