// (book-specific header file)
// (Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡΠ½ΡΠΉ ΡΠ°ΠΉΠ», ΡΠΏΠ΅ΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΠΉ Π΄Π»Ρ Π΄Π°Π½Π½ΠΎΠΉ ΠΊΠ½ΠΈΠ³ΠΈ)
#define COMPOSITE_OFFSET(ClassName, BaseName, \
MemberType, MemberName) \
(DWORD(static_cast<BaseName*>(\
reinterpret_cast<MemberType*>(0x10000000 + \
offsetof(ClassName, MemberName)))) β 0Ρ 10000000)
#define IMPLEMENTS_INTERFACE_WITH_COMPOSITE(Req,\
MemberType, MemberName) \
{ &IID_##Req,ENTRY_IS_OFFSET, COMPOSITE_OFFSET(_IT,\
Req, MemberType, MemberName) },
// impunk.h
// (book-specific header file)
// (Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡΠ½ΡΠΉ ΡΠ°ΠΉΠ», ΡΠΏΠ΅ΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΠΉ Π΄Π»Ρ Π΄Π°Π½Π½ΠΎΠΉ ΠΊΠ½ΠΈΠ³ΠΈ)
#define IMPLEMENT_COMPOSITE_UNKNOWN(OuterClassName,\
InnerClassName, DataMemberName) \
OuterClassName *This() \
{ return (OuterClassName*)((char*)this β \
offsetof(OuterClassName, DataMemberName)); }\
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)\
{ return This()->QueryInterface(riid, ppv); }\
STDMETHODIMP_(ULONG) AddRef(void) \
{ return This()->AddRef(); }\
STDMETHODIMP_(ULONG) Release(void) \
{ return This()->Release(); }
ΠΡΠΈ ΠΌΠ°ΠΊΡΠΎΡΡ ΠΏΡΠ΅ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ° ΠΏΡΠΎΡΡΠΎ Π΄ΡΠ±Π»ΠΈΡΡΡΡ ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ QueryInterface, AddRef ΠΈ Release , ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½Π½ΡΠ΅ Π² ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡΠΈΠΈ.
ΠΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠ°Ρ ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡΠΈΡ
ΠΡΠ»ΠΈ Π΄Π»Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° Π² ΠΊΠ»Π°ΡΡΠ΅ C++ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²Π΅Π½Π½ΠΎΠ΅ Π½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈΠ»ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡΠΈΡ, ΡΠΎ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΎΠ±ΡΠ΅ΠΊΡΠ΅ ΡΡΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ° Π±ΡΠ΄ΡΡ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡΡΡ ΡΠ»ΡΠΆΠ΅Π±Π½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ (overhead) ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ vptr ΡΠ°Π·ΠΌΠ΅ΡΠΎΠΌ Π² ΡΠ΅ΡΡΡΠ΅ Π±Π°ΠΉΡΠ° Π½Π° ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΠΌΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ (ΠΏΡΠΈΠ½ΠΈΠΌΠ°Ρ, ΡΡΠΎ sizeof (void*) == 4). ΠΡΠ»ΠΈ ΡΠΈΡΠ»ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠ², ΡΠΊΡΠΏΠΎΡΡΠΈΡΡΠ΅ΠΌΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠΌ, Π½Π΅Π²Π΅Π»ΠΈΠΊΠΎ, ΡΠΎ ΡΡΠΈ ΡΠ»ΡΠΆΠ΅Π±Π½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ Π½Π΅ ΠΈΠ³ΡΠ°ΡΡ Π²Π°ΠΆΠ½ΠΎΠΉ ΡΠΎΠ»ΠΈ, ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎ Π² ΡΠ²Π΅ΡΠ΅ ΠΏΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ², ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅ΠΌΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΡΡ Π‘ΠΠ. ΠΡΠ»ΠΈ, ΠΎΠ΄Π½Π°ΠΊΠΎ, ΡΠΈΡΠ»ΠΎ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΠΌΡΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠ² Π²Π΅Π»ΠΈΠΊΠΎ, ΡΠΎ ΡΠ°Π·ΠΌΠ΅Ρ ΡΠ»ΡΠΆΠ΅Π±Π½ΡΡ Π΄Π°Π½Π½ΡΡ vptr ΠΌΠΎΠΆΠ΅Ρ Π²ΡΡΠ°ΡΡΠΈ Π΄ΠΎ ΡΠ°ΠΊΠΎΠΉ ΡΡΠ΅ΠΏΠ΅Π½ΠΈ, ΡΡΠΎ ΡΠ°ΡΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ°, Π½Π΅ ΡΠ²ΡΠ·Π°Π½Π½Π°Ρ Ρ Π‘ΠΠ, Π±ΡΠ΄Π΅Ρ ΠΊΠ°Π·Π°ΡΡΡΡ ΠΌΠ°Π»Π΅Π½ΡΠΊΠΎΠΉ ΠΏΠΎ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ Ρ Π½ΠΈΠΌΠΈ. ΠΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΈΠ· ΡΡΠΈΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠ² Π²ΡΠ΅ Π²ΡΠ΅ΠΌΡ Π±Π΅Π· ΡΠ»ΡΠΆΠ΅Π±Π½ΡΡ Π΄Π°Π½Π½ΡΡ Π½Π΅ ΠΎΠ±ΠΎΠΉΡΠΈΡΡ. ΠΡΠ»ΠΈ ΠΆΠ΅, ΠΎΠ΄Π½Π°ΠΊΠΎ, ΡΡΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ Π½Π΅ Π±ΡΠ΄ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Π½ΠΈΠΊΠΎΠ³Π΄Π° ΠΈΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Π² ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ ΠΊΠΎΡΠΎΡΠΊΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ, ΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Π»Π°Π·Π΅ΠΉΠΊΠΎΠΉ Π² Π‘ΠΏΠ΅ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ Π‘ΠΠ ΠΈ ΠΎΠΏΡΠΈΠΌΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ vptr Π½Π΅ΠΊΠΎΡΠΎΡΡΡ Π½Π΅ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ².
ΠΡΠΏΠΎΠΌΠ½ΠΈΠΌ ΠΏΡΠ°Π²ΠΈΠ»ΠΎ, Π³Π»Π°ΡΡΡΠ΅Π΅, ΡΡΠΎ Π²ΡΠ΅ Π·Π°ΠΏΡΠΎΡΡ QueryInterface Π½Π° ΠΎΠ±ΡΠ΅ΠΊΡ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ IUnknown Π΄ΠΎΠ»ΠΆΠ½Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡ ΡΠΎΡΠ½ΠΎ ΡΠ°ΠΊΠΎΠ΅ ΠΆΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ. ΠΠΌΠ΅Π½Π½ΠΎ ΡΠ°ΠΊ Π² Π‘ΠΠ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Π΅ΡΡΡ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ². Π ΡΠΎ ΠΆΠ΅ Π²ΡΠ΅ΠΌΡ Π‘ΠΏΠ΅ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ Π‘ΠΠ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎ ΡΠ°Π·ΡΠ΅ΡΠ°Π΅Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡ Π΄ΡΡΠ³ΠΈΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΉ Π² ΠΎΡΠ²Π΅Ρ Π½Π° Π·Π°ΠΏΡΠΎΡΡ QueryInterface ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ Π»ΡΠ±ΡΡ Π΄ΡΡΠ³ΠΈΡ ΡΠΈΠΏΠΎΠ² ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠ², ΠΊΡΠΎΠΌΠ΅ IUnknown. ΠΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ Π΄Π»Ρ Π½Π΅ΡΠ°ΡΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠ² ΠΎΠ±ΡΠ΅ΠΊΡ ΠΌΠΎΠΆΠ΅Ρ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈ Π²ΡΠ΄Π΅Π»ΡΡΡ ΠΏΠ°ΠΌΡΡΡ Π΄Π»Ρ vptr ΠΏΠΎ ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡ, Π½Π΅ Π·Π°Π±ΠΎΡΡΡΡ ΠΎ Π²ΠΎΠ·Π²ΡΠ°ΡΠ΅ ΡΠΎΠ³ΠΎ ΠΆΠ΅ ΡΠ°ΠΌΠΎΠ³ΠΎ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈ Π²ΡΠ΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ Π±Π»ΠΎΠΊΠ° ΠΏΠ°ΠΌΡΡΠΈ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ°Π·, ΠΊΠΎΠ³Π΄Π° Π·Π°ΠΏΡΠ°ΡΠΈΠ²Π°Π΅ΡΡΡ ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ. ΠΡΠ° ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΡ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ (transient) ΡΠ°Π·ΠΌΠ΅ΡΠ΅Π½ΠΈΡ ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡΠΎΠ² Π²ΠΏΠ΅ΡΠ²ΡΠ΅ Π±ΡΠ»Π° ΠΎΠΏΠΈΡΠ°Π½Π° Π² Β«Π±Π΅Π»ΠΎΠΉ ΠΊΠ½ΠΈΠ³Π΅Β» Microsoft ΠΠΎΠ²Π°ΡΠ΅Π½Π½Π°Ρ ΠΊΠ½ΠΈΠ³Π° Π΄Π»Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΡΠΎΠ² Π‘ΠΠ (Microsoft white paper The Π‘ΠΠ Programmer's Cookbook), Π½Π°ΠΏΠΈΡΠ°Π½Π½ΠΎΠΉ ΠΡΠΈΡΠΏΠΈΠ½ΠΎΠΌ ΠΠΎΡΠ²Π΅Π»Π»ΠΎΠΌ (Crispin Goswell) (http://www.microsoft.com/oledev). Π ΡΡΠΎΠΉ Β«Π±Π΅Π»ΠΎΠΉ ΠΊΠ½ΠΈΠ³Π΅Β» ΡΠ°ΠΊΠΈΠ΅ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ Π½Π°Π·ΡΠ²Π°ΡΡΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΌΠΈ (tearoff).
Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° ΠΏΠΎΠ΄ΠΎΠ±Π½Π° ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡΠΈΠΈ. ΠΠ»Ρ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±ΡΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ Π²ΡΠΎΡΠΎΠΉ ΠΊΠ»Π°ΡΡ, Π½Π°ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΡΠΎΠΌΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΎΠ½ Π±ΡΠ΄Π΅Ρ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²ΡΠ²Π°ΡΡ. Π§ΡΠΎΠ±Ρ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΡΡ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ, QueryInterface ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° Π΄ΠΎΠ»ΠΆΠ΅Π½ Π΄Π΅Π»Π΅Π³ΠΈΡΠΎΠ²Π°ΡΡ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ QueryInterface ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ°. ΠΠ²Π° ΠΎΡΠ½ΠΎΠ²Π½ΡΡ ΡΠ°Π·Π»ΠΈΡΠΈΡ Π·Π°ΠΊΠ»ΡΡΠ°ΡΡΡΡ Π² ΡΠΎΠΌ, ΡΡΠΎ:
1) Π³Π»Π°Π²Π½ΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈ ΡΠ°Π·ΠΌΠ΅ΡΠ°Π΅Ρ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π²ΠΌΠ΅ΡΡΠΎ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΠΈΠΌΠ΅ΡΡ ΡΠ»Π΅ΠΌΠ΅Π½Ρ Π΄Π°Π½Π½ΡΡ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ°, ΠΈ
2) ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΉ ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡ ΡΠ²Π½ΡΠΉ ΠΎΠ±ΡΠ°ΡΠ½ΡΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° Π³Π»Π°Π²Π½ΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΡ ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΡΠΌΠ΅ΡΠ΅Π½ΠΈΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΠ°Ρ Π² ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡΠΈΠΈ, Π·Π΄Π΅ΡΡ Π½Π΅ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ΠΈΠ·ΠΎΠ»ΠΈΡΠΎΠ²Π°Π½ ΠΎΡ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ°. Π‘Π»Π΅Π΄ΡΡΡΠΈΠΉ ΠΊΠ»Π°ΡΡ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅Ρ IBoat ΠΊΠ°ΠΊ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ:
class CarBoat : public ICar
{
LONG m_cRef;
CarBoat (void): m_cRef(0) {}
public:
// IUnknown methods
// ΠΌΠ΅ΡΠΎΠ΄Ρ IUnknown
STDMETHODIMP QueryInterface(REFIID, void**);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// IVehicle methods
// ΠΌΠ΅ΡΠΎΠ΄Ρ IVehicle
STDMETHODIMP GetMaxSpeed(long *pMax);
// ICar methods
// ΠΌΠ΅ΡΠΎΠ΄Ρ ICar
STDMETHODIMP Brake(void);
// define nested class that implements IBoat
// ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌ Π²Π»ΠΎΠΆΠ΅Π½Π½ΡΠΉ ΠΊΠ»Π°ΡΡ, ΡΠ΅Π°Π»ΠΈΠ·ΡΡΡΠΈΠΉ IBoat
struct XBoat : public IBoat
{
LONG m_cBoatRef;
// back pointer to main object is explicit member
// ΠΎΠ±ΡΠ°ΡΠ½ΡΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° Π³Π»Π°Π²Π½ΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ β ΡΠ²Π½ΡΠΉ ΡΠ»Π΅Π½
CarBoat *m_pThis;
inline CarBoat* This()
{
return m_pThis;
}
XBoat(CarBoat *pThis);
~XBoat(void);
STDMETHODIMP QueryInterface(REFIID, void**);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
STDMETHODIMP GetMaxSpeed(long *pval);
STDMETHODIMP Sink(void);
};
// note: no data member of type Xboat
// Π·Π°ΠΌΠ΅ΡΠΈΠΌ: Π½Π΅Ρ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² Π΄Π°Π½Π½ΡΡ ΡΠΈΠΏΠ° Xboat
};
ΠΠ»Ρ QueryInterface Π³Π»Π°Π²Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ° Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈ ΡΠ°Π·ΠΌΠ΅ΡΡΠΈΡΡ Π½ΠΎΠ²ΡΠΉ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ β ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ°Π·, ΠΊΠΎΠ³Π΄Π° Π·Π°ΠΏΡΠ°ΡΠΈΠ²Π°Π΅ΡΡΡ IBoat:
STDMETHODIMP CarBoat::QueryInterface(REFIID riid, void **ppv)
{
if (riid == IID_IBoat)
*ppv = static_cast<IBoat*>(new XBoat(this));
else if (riid == IID_IUnknown)
*ppv = static_cast<IUnknown*>(this);
:
:
:
ΠΠ°ΠΆΠ΄ΡΠΉ ΡΠ°Π· ΠΏΡΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠΈ Π·Π°ΠΏΡΠΎΡΠ° Π½Π° ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ IBoat ΡΠ°Π·ΠΌΠ΅ΡΠ°Π΅ΡΡΡ Π½ΠΎΠ²ΡΠΉ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ. Π‘ΠΎΠ³Π»Π°ΡΠ½ΠΎ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠΉ ΠΏΡΠ°ΠΊΡΠΈΠΊΠ΅ QueryInterface Π²ΡΠ·ΠΎΠ²Π° AddRef ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²ΠΎΠΌ ΡΠ΅Π·ΡΠ»ΡΡΠΈΡΡΡΡΠ΅Π³ΠΎ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ: ((IUnknown*)*ppv)->AddRef();
AddRef Π±ΡΠ΄Π΅Ρ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎ ΠΈΠ· QueryInterface ΡΠΎΠ»ΡΠΊΠΎ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ. ΠΠ°ΠΆΠ½ΠΎ ΡΠΎ, ΡΡΠΎ Π³Π»Π°Π²Π½ΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΎΡΡΠ°Π΅ΡΡΡ Π² ΠΏΠ°ΠΌΡΡΠΈ ΡΡΠΎΠ»ΡΠΊΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ, ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ. ΠΡΠΎΡΡΠ΅ΠΉΡΠΈΠΉ ΠΏΡΡΡ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΡΡ ΡΡΠΎ β Π·Π°ΡΡΠ°Π²ΠΈΡΡ ΡΠ°ΠΌ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΡΡ Π½Π΅ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π΅Π½Π½ΡΡ ΡΡΡΠ»ΠΊΡ. ΠΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ Π² ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ΅ ΠΈ Π΄Π΅ΡΡΡΡΠΊΡΠΎΡΠ΅ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°:
CarBoat::XBoat::XBoat(CarBoat *pThis) : m_cBoatRef(0), m_pThis(pThis)
{
m_pThis->AddRef();
}
CarBoat::XBoat::~XBoat(void)
{
m_pThis->Release();
}
ΠΠ°ΠΊ ΠΈ Π² ΡΠ»ΡΡΠ°Π΅ Ρ ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡΠΈΠ΅ΠΉ, ΠΌΠ΅ΡΠΎΠ΄Ρ QueryInterface ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° ΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΡΠΈΡΠΎΠ²Π°ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ, Π΄Π΅Π»Π΅Π³ΠΈΡΡΡ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ Π³Π»Π°Π²Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ°. ΠΠ΄Π½Π°ΠΊΠΎ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ΠΌΠΎΠΆΠ΅Ρ Π²ΡΡΠ²Π»ΡΡΡ Π·Π°ΠΏΡΠΎΡΡ Π½Π° ΡΠΎΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ (ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ), ΠΊΠΎΡΠΎΡΡΠΉ ΠΎΠ½ ΡΠ°ΠΌ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅Ρ, ΠΈ ΠΏΡΠΎΡΡΠΎ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ, ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°Π½Π½ΡΠΉ AddRef, ΡΠ΅Π±Π΅ ΡΠ°ΠΌΠΎΠΌΡ:
STDMETHODIMP CarBoat::XBoat::QueryInterface(REFIID riid, void**ppv)
{
if (riid != IID_IBoat) return This()->QueryInterface(riid, ppv);
*ppv = static_cast<IBoat*>(this);
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
return S_OK;
}
ΠΠ²ΠΈΠ΄Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠ°ΠΌΠΎΡΠ½ΠΈΡΡΠΎΠΆΠ°ΡΡΡΡ, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ Π±ΠΎΠ»ΡΡΠ΅ Π½Π΅ Π½ΡΠΆΠ΅Π½, ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ ΡΠ²ΠΎΠΉ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠΉ ΡΡΠ΅ΡΡΠΈΠΊ ΡΡΡΠ»ΠΎΠΊ ΠΈ ΡΠ½ΠΈΡΡΠΎΠΆΠ°ΡΡ ΡΠ΅Π±Ρ, ΠΊΠΎΠ³Π΄Π° ΡΡΠΎΡ ΡΡΠ΅ΡΡΠΈΠΊ Π΄ΠΎΡΡΠΈΠ³Π½Π΅Ρ Π½ΡΠ»Ρ. ΠΠ°ΠΊ ΠΎΡΠΌΠ΅ΡΠ°Π»ΠΎΡΡ ΡΠ°Π½Π΅Π΅, Π΄Π΅ΡΡΡΡΠΊΡΠΎΡ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ Π³Π»Π°Π²Π½ΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ Π΄ΠΎ ΡΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΡΠ°ΠΌ ΠΈΡΡΠ΅Π·Π½Π΅Ρ ΠΈΠ· ΠΏΠ°ΠΌΡΡΠΈ:
STDMETHODIMP_(ULONG) CarBoat::XBoat::AddRef (void)
{
return InterlockedIncrement(&m_cRef);
}
STDMETHODIMP_(ULONG) CarBoat::XBoat::Release(void)
{
ULONG res = InterlockedDecrement(&m_cBoatRef);
if (res == 0) delete this;
// dtor releases main object
// Π΄Π΅ΡΡΡΡΠΊΡΠΎΡ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅Ρ Π³Π»Π°Π²Π½ΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ
return res;
}
ΠΠ°ΠΊ ΠΈ Π² ΡΠ»ΡΡΠ°Π΅ Ρ ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡΠΈΠ΅ΠΉ, ΠΌΠ΅ΡΠΎΠ΄ This() ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π² Π»ΡΠ±ΡΡ ΠΌΠ΅ΡΠΎΠ΄Π°Ρ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°, ΠΊΠΎΡΠΎΡΡΠΌ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΡΡΠ°ΡΡΡ Π³Π»Π°Π²Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ°. Π Π°Π·Π½ΠΈΡΠ° ΡΠΎΡΡΠΎΠΈΡ Π² ΡΠΎΠΌ, ΡΡΠΎ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΌ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°ΠΌ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΡΠ²Π½ΡΠΉ ΠΎΠ±ΡΠ°ΡΠ½ΡΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ, Π² ΡΠΎ Π²ΡΠ΅ΠΌΡ ΠΊΠ°ΠΊ Π½ΠΎΡΠΌΠ°Π»ΡΠ½ΡΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡΡ ΠΌΠΎΠ³ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠ΅ ΡΠΌΠ΅ΡΠ΅Π½ΠΈΡ, Π²ΡΠ΄Π΅Π»ΡΡ ΠΏΠΎ ΡΠ΅ΡΡΡΠ΅ Π±Π°ΠΉΡΠ° Π½Π° ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡ.
ΠΠ° ΠΏΠ΅ΡΠ²ΡΠΉ Π²Π·Π³Π»ΡΠ΄, ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠ΅ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ ΠΊΠ°ΠΆΡΡΡΡ Π»ΡΡΡΠ΅ΠΉ ΠΈΠ· Π²ΡΠ΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠ΅ΠΉ. ΠΠΎΠ³Π΄Π° ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ, ΡΠΎ Π½Π° Π΅Π³ΠΎ ΡΠ»ΡΠΆΠ΅Π±Π½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ ΠΎΡΠ²ΠΎΠ΄ΠΈΡΡΡ Π½ΡΠ»Ρ Π±Π°ΠΉΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ°. ΠΠΎΠ³Π΄Π° ΠΆΠ΅ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ, ΠΎΠ±ΡΠ΅ΠΊΡ ΠΊΠΎΡΠ²Π΅Π½Π½ΠΎ ΡΡΠ°ΡΠΈΡ 4 Π±Π°ΠΉΡΠ° Π½Π° ΡΠ»ΡΠΆΠ΅Π±Π½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°. ΠΠΎΠ΄ΠΎΠ±Π½ΠΎΠ΅ Π²ΠΏΠ΅ΡΠ°ΡΠ»Π΅Π½ΠΈΠ΅ Π±Π°Π·ΠΈΡΡΠ΅ΡΡΡ Π½Π° Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΠΎΠ±ΠΌΠ°Π½ΡΠΈΠ²ΡΡ ΠΏΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΡΡ . ΠΠΎ-ΠΏΠ΅ΡΠ²ΡΡ , Π·Π°ΡΡΠ°ΡΡ Π½Π° ΡΠ°Π±ΠΎΡΠ°ΡΡΠΈΠΉ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ΡΠΎΡΡΠ°Π²Π»ΡΡΡ ΠΎΡΠ½ΡΠ΄Ρ Π½Π΅ ΡΠΎΠ»ΡΠΊΠΎ 4 Π±Π°ΠΉΡΠ° ΠΏΠ°ΠΌΡΡΠΈ Π΄Π»Ρ Π΅Π³ΠΎ vptr. ΠΡΠ΄Π΅Π»ΡΠ΅ΠΌΠΎΠΌΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ ΡΡΠ΅Π±ΡΡΡΡΡ ΡΠ°ΠΊΠΆΠ΅ ΠΎΠ±ΡΠ°ΡΠ½ΡΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ ΠΈ ΡΡΠ΅ΡΡΠΈΠΊ ΡΡΡΠ»ΠΎΠΊ[1]. ΠΠΎ-Π²ΡΠΎΡΡΡ , Π½Π΅ΡΠΌΠΎΡΡΡ Π½Π° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΠ΅Π»Ρ ΠΏΠ°ΠΌΡΡΠΈ (custom memory allocator ), ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΠΎΠΌΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ ΠΏΠΎΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΠΏΠΎ ΠΊΡΠ°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅ΡΠ΅ 4 Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ Π±Π°ΠΉΡΠ° Π½Π° Π²ΡΡΠ°Π²Π½ΠΈΠ²Π°Π½ΠΈΠ΅ ΠΈ/ΠΈΠ»ΠΈ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈ Π²ΡΠ΄Π΅Π»Π΅Π½Π½ΠΎΠΉ ΠΏΠ°ΠΌΡΡΠΈ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΡ Π‘-Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΎΠΉ Π΄Π»Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ malloc/operator new . ΠΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ ΠΎΠ±ΡΠ΅ΠΊΡ Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎ ΡΠΊΠΎΠ½ΠΎΠΌΠΈΡ 4 Π±Π°ΠΉΡΠ°, ΠΊΠΎΠ³Π΄Π° ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ. ΠΠΎ ΠΊΠΎΠ³Π΄Π° ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ, ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ΡΡΠ°ΡΠΈΡ ΠΊΠ°ΠΊ ΠΌΠΈΠ½ΠΈΠΌΡΠΌ 12 Π±Π°ΠΉΡ, Π΅ΡΠ»ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΡΠΉ ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΠ΅Π»Ρ ΠΏΠ°ΠΌΡΡΠΈ, ΠΈ 16 Π±Π°ΠΉΡ, Π΅ΡΠ»ΠΈ, ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ, ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ new. ΠΡΠ»ΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π·Π°ΠΏΡΠ°ΡΠΈΠ²Π°Π΅ΡΡΡ ΡΠ΅Π΄ΠΊΠΎ, ΡΠΎ ΡΠ°ΠΊΠ°Ρ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΡ ΠΈΠΌΠ΅Π΅Ρ ΡΠΌΡΡΠ», ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎ Π΅ΡΠ»ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅Ρ ΡΡΠΎΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π²ΡΠΊΠΎΡΠ΅ ΠΏΠΎΡΠ»Π΅ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ. ΠΡΠ»ΠΈ ΠΆΠ΅ ΠΊΠ»ΠΈΠ΅Π½Ρ Ρ ΡΠ°Π½ΠΈΡ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π² ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π²ΡΠ΅Π³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΠΆΠΈΠ·Π½ΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΠ°, ΡΠΎ ΠΏΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ²Π° ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° ΡΠ΅ΡΡΡΡΡΡ.
Π ΡΠΎΠΆΠ°Π»Π΅Π½ΠΈΡ, Π΄Π΅Π»ΠΎ Ρ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΌ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠΌ ΠΎΠ±ΡΡΠΎΠΈΡ Π΅ΡΠ΅ Ρ ΡΠΆΠ΅. ΠΠ°ΠΊ Π²ΠΈΠ΄Π½ΠΎ ΠΈΠ· ΠΏΠΎΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ ΡΠ°Π½Π΅Π΅ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ, Π΅ΡΠ»ΠΈ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΏΠΎΠ»ΡΡΠ°Π΅Ρ Π΄Π²Π° Π·Π°ΠΏΡΠΎΡΠ° QueryInterface Π½Π° ΡΠΎΡ ΠΆΠ΅ ΡΠ°ΠΌΡΠΉ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ, ΡΠΎ Π±ΡΠ΄ΡΡ ΡΠΎΠ·Π΄Π°Π½Ρ Π΄Π²Π΅ ΠΊΠΎΠΏΠΈΠΈ ΡΡΠΎΠ³ΠΎ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΠΏΠ΅ΡΠ²ΡΠΉ ΠΈΠ· Π½ΠΈΡ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ Π·Π°Π±ΡΠ²Π°Π΅ΡΡΡ Π³Π»Π°Π²Π½ΡΠΌ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠΌ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΠ½ Π±ΡΠ» Π²ΠΎΠ·Π²ΡΠ°ΡΠ΅Π½ Π²ΡΠ·ΡΠ²Π°ΡΡΠ΅ΠΌΡ ΠΎΠ±ΡΠ΅ΠΊΡΡ. ΠΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ Π² ΡΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ ΠΏΠΎ ΠΊΡΠ°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅ΡΠ΅ ΠΎΡ 24 Π΄ΠΎ 32 Π±Π°ΠΉΡ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ Π² ΠΏΠ°ΠΌΡΡΠΈ Π½Π°Ρ ΠΎΠ΄ΡΡΡΡ ΠΎΠ±Π° vptr ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°, ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡ Π½Π° ΠΊΠ°ΠΆΠ΄ΡΠΉ Π·Π°ΠΏΡΠΎΡ QueryInterface. ΠΡΠ° ΠΏΠ°ΠΌΡΡΡ Π½Π΅ Π±ΡΠ΄Π΅Ρ Π²ΠΎΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½Π°, ΠΏΠΎΠΊΠ° ΠΊΠ»ΠΈΠ΅Π½Ρ Π½Π΅ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ. Π‘ΠΈΡΡΠ°ΡΠΈΡ, ΠΊΠΎΠ³Π΄Π° Π΄Π²Π° Π·Π°ΠΏΡΠΎΡΠ° QueryInterface ΡΠ΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π² ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π²ΡΠ΅Π³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΠΆΠΈΠ·Π½ΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΠ°, ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎ Π²Π°ΠΆΠ½Π°, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΈΠΌΠ΅Π½Π½ΠΎ ΡΡΠΎ ΠΈ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ ΠΏΡΠΈ ΡΠ΄Π°Π»Π΅Π½Π½ΠΎΠΌ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΠΈ ΠΊ ΠΎΠ±ΡΠ΅ΠΊΡΡ. Π‘ΠΠ-ΡΠ»ΠΎΠΉ, ΡΠ΅Π°Π»ΠΈΠ·ΡΡΡΠΈΠΉ ΡΠ΄Π°Π»Π΅Π½Π½ΡΠ΅ Π²ΡΠ·ΠΎΠ²Ρ, Π±ΡΠ΄Π΅Ρ Π΄Π²Π°ΠΆΠ΄Ρ Π·Π°ΠΏΡΠ°ΡΠΈΠ²Π°ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ (Ρ ΠΏΠΎΠΌΠΎΡΡΡ QueryInterface) Π½Π° ΠΏΡΠ΅Π΄ΠΌΠ΅Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈ ΡΠΎΠ³ΠΎ ΠΆΠ΅ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° ΠΈ Π±ΡΠ΄Π΅Ρ ΡΠ΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ ΠΎΠ±Π° ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ° Π² ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π²ΡΠ΅Π³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΠΆΠΈΠ·Π½ΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΠ°. ΠΡΠΎ ΠΎΠ±ΡΡΠΎΡΡΠ΅Π»ΡΡΡΠ²ΠΎ Π΄Π΅Π»Π°Π΅Ρ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠ΅ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎ ΡΠΈΡΠΊΠΎΠ²Π°Π½Π½ΡΠΌΠΈ Π΄Π»Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ², ΠΊ ΠΊΠΎΡΠΎΡΡΠΌ ΠΌΠΎΠΆΠ΅Ρ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΡΡΡΡ ΡΠ΄Π°Π»Π΅Π½Π½ΡΠΉ Π΄ΠΎΡΡΡΠΏ.