QI(A)->A
ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΈΠ· ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²Π΅Π½Π½ΠΎΠ³ΠΎ Π½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°Π½ΠΈΡ Π²ΡΡΠ΅ΠΊΠ°Π΅Ρ Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½Π°Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ QueryInterface Π΄Π»Ρ Π²ΡΠ΅Ρ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠ² ΠΎΠ±ΡΠ΅ΠΊΡΠ°, Π² Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ ΠΎΡΠ΅Π½Ρ ΡΡΡΠ΄Π½ΠΎ Π½Π°ΡΡΡΠΈΡΡ ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡ ΡΠΈΠΌΠΌΠ΅ΡΡΠΈΡΠ½ΠΎΡΡΠΈ, ΡΡΠ°Π½Π·ΠΈΡΠΈΠ²Π½ΠΎΡΡΠΈ ΠΈ ΡΠ΅ΡΠ»Π΅ΠΊΡΠΈΠ²Π½ΠΎΡΡΠΈ.
Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΡΠ°ΠΊΠΆΠ΅ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ ΠΏΡΠ°Π²ΠΈΠ»ΠΎ Π‘ΠΠ ΠΎΠ± ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ, Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Ρ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ΄Π½ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ ΠΏΡΠΈ Π·Π°ΠΏΡΠΎΡΠ΅ IUnknown:
if (riid == IID_IUnknown) *ppv = static_cast<ICar*>(this);
ΠΡΠ»ΠΈ Π±Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ QueryInterface Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π»Π° ΡΠ°Π·Π»ΠΈΡΠ½ΡΠ΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ vptr Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π·Π°ΠΏΡΠΎΡΠ°:
if (riid == IID_IUnknown)
{
int n = rand() % 3;
if (n == 0) *ppv = static_cast<ICar*>(this);
else if (n == 1) *ppv = static_cast<IBoat*>(this);
else if (n == 2) *ppv = static_cast<IPlane*>(this);
}
ΡΠΎ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ Π±ΡΠ»Π° Π±Ρ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎΠΉ ΡΠΎΠ»ΡΠΊΠΎ Π² ΡΠ΅ΡΠΌΠΈΠ½Π°Ρ ΡΠΈΡΡΠΎ Π‘++-ΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΠΉ ΡΠΈΠΏΠ° (ΡΠΎ Π΅ΡΡΡ Π²ΡΠ΅ ΡΡΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° Π±ΡΠ»ΠΈ Π±Ρ ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΡ ΠΏΠΎ ΡΠΈΠΏΡ Ρ Π·Π°ΠΏΡΠΎΡΠ΅Π½Π½ΡΠΌ ΡΠΈΠΏΠΎΠΌ IUnknown). ΠΡΠ° ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ, ΠΎΠ΄Π½Π°ΠΊΠΎ, Π½Π΅ ΡΠ²Π»ΡΠ΅ΡΡΡ Π΄ΠΎΠΏΡΡΡΠΈΠΌΠΎΠΉ Ρ ΡΠΎΡΠΊΠΈ Π·ΡΠ΅Π½ΠΈΡ Π‘ΠΠ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΏΡΠ°Π²ΠΈΠ»ΠΎ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ Π΄Π»Ρ QueryInterface Π±ΡΠ»ΠΎ Π½Π°ΡΡΡΠ΅Π½ΠΎ.
ΠΠ½ΠΎΠΆΠ΅ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ ΠΈ ΠΈΠΌΠ΅Π½Π° ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ²
ΠΠ½ΠΎΠΆΠ΅ΡΡΠ²Π΅Π½Π½ΠΎΠ΅ Π½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΎΡΠ΅Π½Ρ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎΠΉ ΠΈ ΠΏΡΠΎΡΡΠΎΠΉ ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΠ΅ΠΉ Π΄Π»Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠ² Π‘ΠΠ Π² ΠΊΠ»Π°ΡΡΠ΅ C++. ΠΡΠΎ ΡΡΠ΅Π±ΡΠ΅Ρ Π½Π°ΠΏΠΈΡΠ°Π½ΠΈΡ ΠΎΡΠ΅Π½Ρ ΠΊΠΎΡΠΎΡΠΊΠΎΠ³ΠΎ ΡΠ²Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°, ΡΠ°ΠΊ ΠΊΠ°ΠΊ Π±ΠΎΠ»ΡΡΠ°Ρ ΡΠ°ΡΡΡ ΡΠ°Π±ΠΎΡΡ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΠ° ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²ΡΠΈΠΊΠ° Π·Π°ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ Π² ΠΏΠΎΡΡΡΠΎΠ΅Π½ΠΈΠΈ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΡ Π‘ΠΠ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΉ vptr ΠΈ ΡΠ°Π±Π»ΠΈΡ vtbl. ΠΡΠ»ΠΈ ΠΈΠΌΡ ΠΌΠ΅ΡΠΎΠ΄Π° ΠΏΠΎΡΠ²Π»ΡΠ΅ΡΡΡ Π±ΠΎΠ»Π΅Π΅ ΡΠ΅ΠΌ Π² ΠΎΠ΄Π½ΠΎΠΌ Π±Π°Π·ΠΎΠ²ΠΎΠΌ ΠΊΠ»Π°ΡΡΠ΅ Ρ ΠΈΠ΄Π΅Π½ΡΠΈΡΠ½ΡΠΌΠΈ ΡΠΈΠΏΠ°ΠΌΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ², ΡΠΎ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²ΡΠΈΠΊ Π·Π°ΠΏΠΎΠ»Π½ΡΡΡ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ vtbl ΡΠ°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, ΡΡΠΎΠ±Ρ ΠΎΠ½ ΡΠΊΠ°Π·ΡΠ²Π°Π» Π½Π° ΠΎΠ΄Π½Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΌΠ΅ΡΠΎΠ΄Π° Π² ΠΊΠ»Π°ΡΡΠ΅. ΠΡΠΎΡ ΡΠ΅ΠΆΠΈΠΌ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΡΡΡ ΠΊ ΡΠ°ΠΊΠΈΠΌ ΠΌΠ΅ΡΠΎΠ΄Π°ΠΌ, ΠΊΠ°ΠΊ QueryInterface, AddRef ΠΈ Release, ΡΠ°ΠΊ ΠΊΠ°ΠΊ Π²ΡΠ΅ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ Π‘ΠΠ Π½Π°ΡΠΈΠ½Π°ΡΡΡΡ Ρ ΡΡΠΈΡ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ², ΠΈ Π²ΡΠ΅ ΠΆΠ΅ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΡ ΠΊΠ»Π°ΡΡΠ° ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π½Π°ΠΏΠΈΡΠ°ΡΡ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΡΠ°Π· (ΠΈ ΡΡΠΎ Ρ ΠΎΡΠΎΡΠΎ). ΠΡΠΎΡ ΠΆΠ΅ ΡΠ΅ΠΆΠΈΠΌ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΡΡΡ ΠΈ ΠΊ ΠΌΠ΅ΡΠΎΠ΄Π°ΠΌ Π»ΡΠ±ΡΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠ², Π³Π΄Π΅ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ ΠΏΠΎΠ²ΡΠΎΡ ΠΈΠΌΠ΅Π½ΠΈ ΠΈ ΡΠΈΠ³Π½Π°ΡΡΡΡ. ΠΠ΄Π΅ΡΡ Π΅ΡΡΡ ΠΎΠ΄Π½Π° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π°Ρ Π»ΠΎΠ²ΡΡΠΊΠ° ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²Π΅Π½Π½ΠΎΠ³ΠΎ Π½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°Π½ΠΈΡ.
ΠΠ΅ΡΠ°ΡΡ ΠΈΡ ΡΡΠ°Π½ΡΠΏΠΎΡΡΠ½ΡΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠ² ΠΈΠ· ΡΡΠΎΠΉ Π³Π»Π°Π²Ρ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡ ΠΈΠΌΠ΅Π½. Π ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ΅ ICar (Π°Π²ΡΠΎΠΌΠΎΠ±ΠΈΠ»Ρ) ΠΈΠΌΠ΅Π΅ΡΡΡ ΠΌΠ΅ΡΠΎΠ΄, Π½Π°Π·Π²Π°Π½Π½ΡΠΉ GetMaxSpeed (ΡΠ°Π·Π²ΠΈΡΡ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΡΡ ΡΠΊΠΎΡΠΎΡΡΡ). Π ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°Ρ IBoat (Π»ΠΎΠ΄ΠΊΠ°) ΠΈ IPlane (ΡΠ°ΠΌΠΎΠ»Π΅Ρ) ΡΠ°ΠΊΠΆΠ΅ ΠΈΠΌΠ΅ΡΡΡΡ ΠΌΠ΅ΡΠΎΠ΄Ρ, ΠΈΠΌΠ΅Π½ΡΠ΅ΠΌΡΠ΅ GetMaxSpeed Ρ ΠΈΠ΄Π΅Π½ΡΠΈΡΠ½ΠΎΠΉ ΡΠΈΠ³Π½Π°ΡΡΡΠΎΠΉ. ΠΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²Π΅Π½Π½ΠΎΠ³ΠΎ Π½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°Π½ΠΈΡ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΠΊΠ»Π°ΡΡΠ° ΠΏΠΈΡΠ΅Ρ ΠΌΠ΅ΡΠΎΠ΄ GetMaxSpeed ΠΎΠ΄ΠΈΠ½ ΡΠ°Π·, Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²ΡΠΈΠΊ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΡΡ ΡΠ°Π±Π»ΠΈΡΡ vtbl , ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΡΠ΅ Ρ ICar, IBoat ΠΈ IPlane ΡΠ°ΠΊ, ΡΡΠΎΠ±Ρ ΠΎΠ½ΠΈ ΡΠΊΠ°Π·ΡΠ²Π°Π»ΠΈ ΡΠΎΠ»ΡΠΊΠΎ Π½Π° ΡΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ.
ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΡΡΠΎ Π²ΠΏΠΎΠ»Π½Π΅ ΡΠ°Π·ΡΠΌΠ½ΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π΄Π»Ρ Π±ΠΎΠ»ΡΡΠΎΠ³ΠΎ ΡΠΈΡΠ»Π° ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ. ΠΠΎ ΡΡΠΎ Π΅ΡΠ»ΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΡ Π½ΡΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ Π²Π΅ΡΠ½ΡΡΡ Π΄ΡΡΠ³ΡΡ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΡΡ ΡΠΊΠΎΡΠΎΡΡΡ, Π·Π°Π²ΠΈΡΡΡΡΡ ΠΎΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°, Π½Π° ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ» ΡΠ΄Π΅Π»Π°Π½ Π·Π°ΠΏΡΠΎΡ? ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΈΠΌΡ ΠΈ ΡΠΈΠ³Π½Π°ΡΡΡΡ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ, ΡΠΎ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡΠΈΠ½ΠΈΠΌΠ°ΡΡ Π½Π΅ΠΎΡΠ΄ΠΈΠ½Π°ΡΠ½ΡΠ΅ ΠΌΠ΅ΡΡ Π΄Π»Ρ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΈΡ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²Π΅Π½Π½ΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠ½ΠΎΠ³ΠΎ ΠΌΠ΅ΡΠΎΠ΄Π°. ΠΠ΄ΠΈΠ½ ΠΈΠ· Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΡ ΡΠΏΠΎΡΠΎΠ±ΠΎΠ² ΡΠΎΡΡΠΎΠΈΡ Π² ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΎΡΠ½ΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ° C++, ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΎΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° ΠΈ ΡΠ΅Π°Π»ΠΈΠ·ΡΡΡΠ΅Π³ΠΎ ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ ΠΏΡΡΠ΅ΠΌ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΠΈΡΡΠΎ Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΠΎΠ³ΠΎ Π²ΡΠ·ΠΎΠ²Π° Π½Π΅ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠ½ΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ:
struct IXCar : public ICar {
// add new non-clashing method as pure virtual
// Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ Π½ΠΎΠ²ΡΠΉ Π½Π΅ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ ΠΊΠ°ΠΊ ΡΠΈΡΡΠΎ Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΡΠΉ
virtual HRESULT STDMETHODCALLTYPE GetMaxCarSpeed(long *pval) = 0;
// implement clashing method by upcalling
// non-clashing implementation in derived class
// ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅ΠΌ ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ ΠΏΡΡΠ΅ΠΌ Π²ΡΠ·ΠΎΠ²Π°
// Π½Π΅ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠ½ΠΎΠΉ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ Π² ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»Π°ΡΡΠ΅
STDMETHODIMP GetMaxSpeed(long *pval)
{ return GetMaxCarSpeed(pval); }
};
ΠΠΎΠΏΡΡΠΊΠ°Ρ, ΡΡΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ IBoat ΠΈ IPlane ΠΏΠΎΠ΄Π²Π΅ΡΠ³Π½ΡΡΡ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ, ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²ΡΠ²Π°ΡΡ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠ΅ Π²Π΅ΡΡΠΈΠΈ GetMaxSpeed ΠΏΡΠΎΡΡΡΠΌ Π½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΎΡ ΡΠ°ΡΡΠΈΡΠ΅Π½Π½ΡΡ Π²Π΅ΡΡΠΈΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠ² ΠΈ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ΠΌ Π½Π΅ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠ½ΡΡ Π²Π΅ΡΡΠΈΠΉ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΌΠ΅ΡΠΎΠ΄Π° GetMaxSpeed:
class CarBoatPlane: public IXCar, public IXBoat, public IXPlane
{
public:
// Unknown methods β ΠΌΠ΅ΡΠΎΠ΄Ρ IUnknown
STDMETHODIMP QueryInterface(REFIID, void**);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// IVehicle methods β ΠΌΠ΅ΡΠΎΠ΄Ρ IVehicle
// do not override GetMaxSpeed!
// Π½Π΅ ΠΏΠΎΠ΄ΠΌΠ΅Π½ΡΠ΅ΠΌ GetMaxSpeed!
// ICar methods β ΠΌΠ΅ΡΠΎΠ΄Ρ ICar
STDMETHODIMP Brake(void);
// IBoat methods β ΠΌΠ΅ΡΠΎΠ΄Ρ IBoat
STDMETHODIMP Sink(void);
// IXPlane methods β ΠΌΠ΅ΡΠΎΠ΄Ρ IXPlane
STDMETHODIMP TakeOff(void);
// upcalled from IXCar::GetMaxSpeed
// Π²ΡΠ·Π²Π°Π½ΠΎ ΠΈΠ· IXCar::GetMaxSpeed
STDMETHODIMP GetMaxCarSpeed(long *pval);
// upcalled from IXBoat::GetMaxSpeed
// Π²ΡΠ·Π²Π°Π½ΠΎ ΠΈΠ· IXBoat::GetMaxSpeed
STDMETHODIMP GetMaxBoatSpeed(long *pval);
// called from IXPlane::GetMaxSpeed
// Π²ΡΠ·Π²Π°Π½ΠΎ ΠΈΠ· IXPlane::GetMaxSpeed
STDMETHODIMP GetMaxPlaneSpeed(long *pval);
}
Π ΠΈΡΡΠ½ΠΎΠΊ 4.6 ΠΈΠ»Π»ΡΡΡΡΠΈΡΡΠ΅Ρ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΡΡΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ° ΠΈ ΡΠΎΡΠΌΠ°ΡΡ ΡΠ°Π±Π»ΠΈΡ vtbl. ΠΡΠΌΠ΅ΡΠΈΠΌ, ΡΡΠΎ ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ GetMaxSpeed Π½Π΅ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Π² ΡΡΠΎΠΌ ΠΊΠ»Π°ΡΡΠ΅. ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΈΠ· Π±Π°Π·ΠΎΠ²ΡΡ ΠΊΠ»Π°ΡΡΠΎΠ² CarBoatPlane ΠΏΠΎΠ΄ΠΌΠ΅Π½ΡΠ΅Ρ ΡΡΠΎΡ ΡΠΈΡΡΠΎ Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄, ΡΠΎ CarBoatPlane Π½Π΅ Π½ΡΠΆΠ΄Π°Π΅ΡΡΡ Π² ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ ΡΠ²ΠΎΠ΅ΠΉ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΠΎΠΉ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ. ΠΠ΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎ, Π΅ΡΠ»ΠΈ Π±Ρ Π² CarBoatPlane Π½ΡΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ ΠΏΠΎΠ΄ΠΌΠ΅Π½ΠΈΡΡ GetMaxSpeed, ΡΠΎ ΠΎΠ΄Π½Π° Π΅Π³ΠΎ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΡΡΠΎΠ³ΠΎ ΠΌΠ΅ΡΠΎΠ΄Π° ΠΏΠΎΠ΄ΠΌΠ΅Π½ΠΈΠ»Π° Π±Ρ Π²Π΅ΡΡΠΈΠΈ, Π²ΡΠ·ΡΠ²Π°Π΅ΠΌΡΠ΅ ΠΈΠ· ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ°, Π°Π½Π½ΡΠ»ΠΈΡΠΎΠ²Π°Π² ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ IXCar, IXBoat ΠΈ IXPlane. Π ΡΠΈΠ»Ρ ΡΡΠΎΠΉ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Π΄Π°Π½Π½Π°Ρ ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΡ Π³ΠΎΠ΄ΠΈΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ Π² ΡΠ΅Ρ ΡΠΈΡΡΠ°ΡΠΈΡΡ , ΠΊΠΎΠ³Π΄Π° ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΡΡ ΡΠ²Π΅ΡΠ΅Π½Π½ΡΠΌ, ΡΡΠΎ ΠΊΠ»Π°ΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ (ΠΈΠ»ΠΈ Π»ΡΠ±ΡΠ΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΠ΅ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΡΠ΅ ΠΊΠ»Π°ΡΡΡ) Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΡΡΠ°Π½Π΅Ρ ΠΏΠΎΠ΄ΠΌΠ΅Π½ΡΡΡ ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄.
ΠΡΡΠ³ΠΎΠΉ ΡΠΏΠΎΡΠΎΠ± ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠ΅Π½ΠΈΡ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²Π΅Π½Π½ΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠ½ΡΡ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² ΡΠΎΡΡΠΎΠΈΡ Π² ΡΠΎΠΌ, ΡΡΠΎΠ±Ρ ΡΡΠΈΠ»ΠΈΡΡ ΠΏΡΠ°Π²ΠΈΠ»Π° IUnknown . Π‘ΠΏΠ΅ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ Π‘ΠΠ Π½Π΅ ΡΡΠ΅Π±ΡΠ΅Ρ, ΡΡΠΎΠ±Ρ ΠΎΠ±ΡΠ΅ΠΊΡ Π±ΡΠ» ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ ΠΊΠ°ΠΊ ΠΊΠ»Π°ΡΡ C++. Π₯ΠΎΡΡ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ Π²Π΅ΡΡΠΌΠ° Π΅ΡΡΠ΅ΡΡΠ²Π΅Π½Π½ΠΎΠ΅ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠ°ΠΌΠΈ Π‘ΠΠ ΠΈ ΠΊΠ»Π°ΡΡΠ°ΠΌΠΈ C++, Π±Π°Π·ΠΈΡΡΡΡΠΈΠΌΠΈΡΡ Π½Π° ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²Π΅Π½Π½ΠΎΠΌ Π½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°Π½ΠΈΠΈ, ΡΡΠΎ Π²ΡΠ΅Π³ΠΎ Π»ΠΈΡΡ ΠΎΠ΄Π½Π° ΠΈΠ· Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΡ ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΠΉ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ. ΠΠ»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ° Π‘ΠΠ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½Π° Π»ΡΠ±Π°Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½Π°Ρ ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΡ, ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΡΡΠ°Ρ ΡΠ°Π±Π»ΠΈΡΡ vtbl Π² Π½ΡΠΆΠ½ΠΎΠΌ ΡΠΎΡΠΌΠ°ΡΠ΅ ΠΈ ΡΠ΄ΠΎΠ²Π»Π΅ΡΠ²ΠΎΡΡΡΡΠ°Ρ ΠΏΡΠ°Π²ΠΈΠ»Π°ΠΌ Π‘ΠΠ Π΄Π»Ρ QueryInterface. ΠΠ΄ΠΈΠ½ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΈΡ ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠΎΠ² ΠΈΠΌΠ΅Π½ ΡΠΎΡΡΠΎΠΈΡ Π² ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠ² Ρ ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΡΡΡΠΈΠΌΠΈ ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ ΠΊΠ°ΠΊ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΡ ΠΊΠ»Π°ΡΡΠΎΠ² C++ ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²ΠΊΠ΅ ΡΠ΅Π»Π΅Π²ΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ° C++ ΠΈΠ· ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΎΠ² ΡΡΠΈΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΡ ΠΊΠ»Π°ΡΡΠΎΠ². ΠΠ»Ρ Π³Π°ΡΠ°Π½ΡΠΈΠΈ ΡΠΎΠ³ΠΎ, ΡΡΠΎ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΈΠ· ΡΡΠΈΡ ΡΠΎΡΡΠ°Π²Π½ΡΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² Π΄Π°Π½Π½ΡΡ ΠΏΠΎΡΠ²ΠΈΡΡΡ Π²ΠΎ Π²Π½Π΅ΡΠ½Π΅ΠΌ ΠΌΠΈΡΠ΅ ΠΊΠ°ΠΊ Π΅Π΄ΠΈΠ½ΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ Π‘ΠΠ, ΡΠ°ΡΡΠΎ Π½Π°Π·Π½Π°ΡΠ°Π΅ΡΡΡ ΠΎΠ΄Π½Π° Π³Π»Π°Π²Π½Π°Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ QueryInterface, ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠΎΡΡΠ°Π²Π½ΠΎΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ Π΄Π°Π½Π½ΡΡ Π±ΡΠ΄Π΅Ρ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ. Π‘Π»Π΅Π΄ΡΡΡΠΈΠΉ ΠΊΠΎΠ΄ Π΄Π΅ΠΌΠΎΠ½ΡΡΡΠΈΡΡΠ΅Ρ ΡΡΡ ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΡ:
class CarPlane
{
LONG m_cRef;
CarPlane(void) : m_cRef(0) {}
public:
// Main IUnknown methods
// ΠΠ»Π°Π²Π½ΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄Ρ IUnknown
STDMETHODIMP QueryInterface(REFIID, void**);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
private:
// define nested class that implements ICar
// ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌ Π²Π»ΠΎΠΆΠ΅Π½Π½ΡΠΉ ΠΊΠ»Π°ΡΡ, ΡΠ΅Π°Π»ΠΈΠ·ΡΡΡΠΈΠΉ
ICar struct XCar : public ICar
{
// get back pointer to main object
// ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ ΠΎΠ±ΡΠ°ΡΠ½ΡΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° Π³Π»Π°Π²Π½ΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ
inline CarPlane* This();
STDMETHODIMP QueryInterface(REFIID, void**);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
STDMETHODIMP GetMaxSpeed(long *pval);
STDMETHODIMP Brake(void);
};
// define nested class that implements IPlane
// ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌ Π²Π»ΠΎΠΆΠ΅Π½Π½ΡΠΉ ΠΊΠ»Π°ΡΡ, ΡΠ΅Π°Π»ΠΈΠ·ΡΡΡΠΈΠΉ IPlane
struct XPlane : public IPlane {
// Get back pointer to main object
// ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ ΠΎΠ±ΡΠ°ΡΠ½ΡΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° Π³Π»Π°Π²Π½ΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ
inline CarPlane* This();
STDMETHODIMP QueryInterface(REFIID, void**);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
STDMETHODIMP GetMaxSpeed(long *pval);
STDMETHODIMP TakeOff(void);
};
// declare instances of nested classes
// ΠΎΠ±ΡΡΠ²Π»ΡΠ΅ΠΌ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΡ Π²Π»ΠΎΠΆΠ΅Π½Π½ΡΡ ΠΊΠ»Π°ΡΡΠΎΠ²
XCar m_xCar;
XPlane m_xPlane;
};
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π²Π»ΠΎΠΆΠ΅Π½Π½ΡΡ ΠΊΠ»Π°ΡΡΠΎΠ² Π½Π΅ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΡΠΌ, Π½ΠΎ ΠΎΠ½ΠΎ ΠΏΠΎΠ΄ΡΠ΅ΡΠΊΠΈΠ²Π°Π΅Ρ, ΡΡΠΎ ΡΡΠΈ ΠΏΠΎΠ΄ΡΠΈΠ½Π΅Π½Π½ΡΠ΅ ΠΊΠ»Π°ΡΡΡ Π½Π΅ ΠΈΠΌΠ΅ΡΡ ΡΠΌΡΡΠ»Π° Π²Π½Π΅ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ° ΠΊΠ»Π°ΡΡΠ° CarPlane. Π ΠΈΡΡΠ½ΠΎΠΊ 4.7 ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°Π΅Ρ Π΄Π²ΠΎΠΈΡΠ½ΠΎΠ΅ ΡΠ°Π·ΠΌΠ΅ΡΠ΅Π½ΠΈΠ΅ ΡΡΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ° ΠΈ ΡΠ°Π·ΠΌΠ΅ΡΠ΅Π½ΠΈΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΡ vtbl .
ΠΡΠΌΠ΅ΡΠΈΠΌ, ΡΡΠΎ ΠΈΠΌΠ΅Π΅ΡΡΡ Π΄Π²Π° ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ°, ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΈΠΌ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°. ΠΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ° ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΡΡ Π΄Π²Π΅ ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ GetMaxSpeed:
STDMETHODIMP CarPlane::XCar::GetMaxSpeed(long *pn) {
// set *pn to max speed for cars
// ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ *pn Π΄Π»Ρ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎΠΉ ΡΠΊΠΎΡΠΎΡΡΠΈ Π°Π²ΡΠΎΠΌΠΎΠ±ΠΈΠ»Π΅ΠΉ
}
STDMETHODIMP CarPlane::XPlane::GetMaxSpeed(long *pn) {
// set *pn to max speed for planes
// ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ *pn Π΄Π»Ρ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎΠΉ ΡΠΊΠΎΡΠΎΡΡΠΈ ΡΠ°ΠΌΠΎΠ»Π΅ΡΠΎΠ²
}
Π’ΠΎΡ ΡΠ°ΠΊΡ, ΡΡΠΎ Π΄Π²Π΅ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ GetMaxSpeed Π²ΡΡΡΠ΅ΡΠ°ΡΡΡΡ Π² ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡΡ Π²Π»ΠΎΠΆΠ΅Π½Π½ΡΡ ΠΊΠ»Π°ΡΡΠΎΠ², ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ ΠΌΠ΅ΡΠΎΠ΄ Π΄Π²Π°ΠΆΠ΄Ρ ΠΈ ΠΊ ΡΠΎΠΌΡ ΠΆΠ΅ Π³Π°ΡΠ°Π½ΡΠΈΡΡΠ΅Ρ ΡΠΎ, ΡΡΠΎ ΡΠ°Π±Π»ΠΈΡΡ vtbl, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠ΅ ICar ΠΈ IPlane, Π±ΡΠ΄ΡΡ ΠΈΠΌΠ΅ΡΡ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ Π΄Π»Ρ GetMaxSpeed.
ΠΠ΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΠ°ΠΊΠΆΠ΅ ΠΎΡΠΌΠ΅ΡΠΈΡΡ, ΡΡΠΎ Ρ ΠΎΡΡ ΠΊΠ»Π°ΡΡ CarPlane, Π½Π°Ρ ΠΎΠ΄ΡΡΠΈΠΉΡΡ Π½Π° Π²Π΅ΡΡ Π½Π΅ΠΌ ΡΡΠΎΠ²Π½Π΅, ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅Ρ ΠΌΠ΅ΡΠΎΠ΄Ρ IUnknown, ΠΎΠ½ Π½Π΅ Π½Π°ΡΠ»Π΅Π΄ΡΠ΅Ρ Π½ΠΈΠΊΠ°ΠΊΠΎΠΌΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΠΎΠΌΡ ΠΎΡ IUnknown ΠΊΠ»Π°ΡΡΡ. ΠΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΡ CarPlane ΠΈΠΌΠ΅ΡΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ Π΄Π°Π½Π½ΡΡ , ΠΊΠΎΡΠΎΡΡΠ΅ Π½Π°ΡΠ»Π΅Π΄ΡΡΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°ΠΌ Π‘ΠΠ. ΠΡΠΎ Π·Π½Π°ΡΠΈΡ, ΡΡΠΎ Π²ΠΌΠ΅ΡΡΠΎ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ static_cast Π΄Π»Ρ Π²Ρ ΠΎΠΆΠ΄Π΅Π½ΠΈΡ Π² ΠΎΠ±ΡΠ΅ΠΊΡ ΠΈ Π½Π°Ρ ΠΎΠΆΠ΄Π΅Π½ΠΈΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ vptr, ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ QueryInterface Π² CarPlane Π΄ΠΎΠ»ΠΆΠ½Π° Π²ΠΎΠ·Π²ΡΠ°ΡΠΈΡΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΡΠΎΡ ΡΠ»Π΅ΠΌΠ΅Π½Ρ Π΄Π°Π½Π½ΡΡ , ΠΊΠΎΡΠΎΡΡΠΉ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅Ρ Π·Π°ΠΏΡΠ°ΡΠΈΠ²Π°Π΅ΠΌΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ: