{
LONG mcRef;
protected:
virtual ~PugCat(void);
public: PugCat(void);
// IUnknown methods
// ΠΌΠ΅ΡΠΎΠ΄Ρ IUnknown
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
STDMETHODIMP(ULONG) AddRef(void);
STDMETHODIMP(ULONG) Release(void);
// IAnimal methods
// ΠΌΠ΅ΡΠΎΠ΄Ρ IAnimal
STDMETHODIMP Eat(void);
// IDog methods
// ΠΌΠ΅ΡΠΎΠ΄Ρ IDog
STDMETHODIMP Bark(void);
// IPug methods
// ΠΌΠ΅ΡΠΎΠ΄Ρ IPug
STDMETHODIMP Snore(void);
// ICat methods
// ΠΌΠ΅ΡΠΎΠ΄Ρ ICat
STDMETHODIMP IgnoreMaster(void);
};
ΠΡΠΌΠ΅ΡΠΈΠΌ, ΡΡΠΎ Π² ΠΊΠ»Π°ΡΡΠ΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±ΡΡΡ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄, ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠΉ Π² Π»ΡΠ±ΠΎΠΌ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ΅, ΠΎΡ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ ΠΎΠ½ Π½Π°ΡΠ»Π΅Π΄ΡΠ΅Ρ, ΡΠ°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ΠΈ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄, ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠΉ Π² Π»ΡΠ±ΡΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΡΡ (implied) Π±Π°Π·ΠΎΠ²ΡΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°Ρ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, IDog, IAnimal ). ΠΠ»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΡΠ΅ΠΊΠΎΠ²ΡΡ ΡΡΠ΅ΠΉΠΌΠΎΠ², ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΡΡ Ρ Π‘ΠΠ, Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΌΠ°ΠΊΡΠΎΡΡ STDMETHODIMP ΠΈ STDMETHODIMP. ΠΡΠΈ ΠΎΡΠΈΠ΅Π½ΡΠ°ΡΠΈΠΈ Π½Π° ΠΏΠ»Π°ΡΡΠΎΡΠΌΡ Win32, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ Microsoft C++, Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ SDK ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡ ΡΡΠΈ Π΄Π²Π° ΠΌΠ°ΠΊΡΠΎΡΠ° ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
#define STDMETHODIMP HRESULT stdcall
#define STDMETHODIMP(type) type stdcall
ΠΠ°Π³ΠΎΠ»ΠΎΠ²ΠΎΡΠ½ΡΠ΅ ΡΠ°ΠΉΠ»Ρ SDK ΡΠ°ΠΊΠΆΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡ ΠΌΠ°ΠΊΡΠΎΡΡ STDMETHOD ΠΈ STDMETHOD , ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΏΡΠΈ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠ² Π±Π΅Π· IDL-ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΠ°. Π ΡΠ΅ΡΠΈΠΉΠ½ΠΎ Π²ΡΠΏΡΡΠΊΠ°Π΅ΠΌΠΎΠΌ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠΈ Π½Π° Π‘ΠΠ ΡΡΠΈ Π΄Π²Π° ΠΌΠ°ΠΊΡΠΎΡΠ° Π½Π΅ Π½ΡΠΆΠ½Ρ.
Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ AddRef ΠΈ Release ΡΡΠ΅Π·Π²ΡΡΠ°ΠΉΠ½ΠΎ ΠΏΡΠΎΠ·ΡΠ°ΡΠ½Π°. ΠΠ»Π΅ΠΌΠ΅Π½Ρ Π΄Π°Π½Π½ΡΡ mcRef ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π΅Ρ, ΡΠΊΠΎΠ»ΡΠΊΠΎ Π½Π΅ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π΅Π½Π½ΡΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ½ΡΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΉ ΡΠ΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ. ΠΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ ΠΊΠ»Π°ΡΡΠ° ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΡ ΡΡΠ΅ΡΡΠΈΠΊ ΡΡΡΠ»ΠΎΠΊ Π² Π½ΡΠ»Π΅Π²ΠΎΠ΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅:
PugCat::PugCat(void) : mcRef(0)
// initialize reference count to zero
// ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ ΡΡΠ΅ΡΡΠΈΠΊ ΡΡΡΠ»ΠΎΠΊ Π² Π½ΡΠ»Ρ
{ }
Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ AddRef Π² ΠΊΠ»Π°ΡΡΠ΅ ΡΠΈΠΊΡΠΈΡΡΠ΅Ρ ΠΏΡΡΠ΅ΠΌ ΡΠ²Π΅Π»ΠΈΡΠ΅Π½ΠΈΡ ΡΡΠ΅ΡΡΠΈΠΊΠ° ΡΡΡΠ»ΠΎΠΊ, ΡΡΠΎ Π²ΡΠ·ΡΠ²Π°ΡΡΠΈΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΏΡΠΎΠ΄ΡΠ±Π»ΠΈΡΠΎΠ²Π°Π» ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°. ΠΠ·ΠΌΠ΅Π½Π΅Π½Π½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΡΠ΅ΡΡΠΈΠΊΠ° ΡΡΡΠ»ΠΎΠΊ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΡΡΡ Π΄Π»Ρ ΡΠ΅Π»Π΅ΠΉ Π΄ΠΈΠ°Π³Π½ΠΎΡΡΠΈΠΊΠΈ:
STDMETHODIMP(ULONG) AddRef(void)
{ return ++mcRef; }
Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ Release ΡΠΈΠΊΡΠΈΡΡΠ΅Ρ ΡΠ½ΠΈΡΡΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° ΠΏΡΠΎΡΡΡΠΌ ΡΠΌΠ΅Π½ΡΡΠ΅Π½ΠΈΠ΅ΠΌ ΡΡΠ΅ΡΡΠΈΠΊΠ° ΡΡΡΠ»ΠΎΠΊ, Π° ΡΠ°ΠΊΠΆΠ΅ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅Π΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅, ΠΊΠΎΠ³Π΄Π° ΡΡΠ΅ΡΡΠΈΠΊ ΡΡΡΠ»ΠΎΠΊ Π΄ΠΎΡΡΠΈΠ³Π°Π΅Ρ Π½ΡΠ»Ρ. ΠΠ»Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ², Π½Π°Ρ ΠΎΠ΄ΡΡΠΈΡ ΡΡ Π² Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈ ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌΠΎΠΉ ΠΎΠ±Π»Π°ΡΡΠΈ ΠΏΠ°ΠΌΡΡΠΈ, ΡΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ Π²ΡΠ·ΠΎΠ² ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ° delete Π΄Π»Ρ ΡΠ½ΠΈΡΡΠΎΠΆΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ°:
STDMETHODIMP(ULONG) Release(void)
{
LONG res = -mcRef;
if (res == 0) delete this;
return res;
}
ΠΠ»Ρ ΠΊΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΡΡΠ΅ΡΡΠΈΠΊΠ° ΡΡΡΠ»ΠΎΠΊ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ Π½Π΅Π»ΡΠ·Ρ ΠΎΠ±ΡΠ°ΡΠ°ΡΡΡΡ ΠΊ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°ΠΌ Π΄Π°Π½Π½ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ° ΠΏΠΎΡΠ»Π΅ ΡΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΎΠ±ΡΠ΅ΠΊΡ ΡΠΆΠ΅ ΡΠ½ΠΈΡΡΠΎΠΆΠ΅Π½.
ΠΠ°ΠΌΠ΅ΡΠΈΠΌ, ΡΡΠΎ ΠΏΠΎΠΊΠ°Π·Π°Π½Π½ΡΠ΅ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ Addref ΠΈ Release ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΡ ΠΈΠ½ΠΊΡΠ΅ΠΌΠ΅Π½ΡΠ° ΠΈ Π΄Π΅ΠΊΡΠ΅ΠΌΠ΅Π½ΡΠ° (ΡΠ²Π΅Π»ΠΈΡΠ΅Π½ΠΈΡ ΠΈ ΡΠΌΠ΅Π½ΡΡΠ΅Π½ΠΈΡ Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡΡ). ΠΠ»Ρ ΠΏΡΠΎΡΡΠΎΠΉ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΡΡΠΎ Π²Π΅ΡΡΠΌΠ° ΡΠ°Π·ΡΠΌΠ½ΠΎ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ Π‘ΠΠ Π½Π΅ Π΄ΠΎΠΏΡΡΠΊΠ°Π΅Ρ Π±ΠΎΠ»Π΅Π΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° Π΄Π»Ρ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΡ ΠΊ ΠΎΠ±ΡΠ΅ΠΊΡΡ Π΄ΠΎ ΡΠ΅Ρ ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ Π½Π΅ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΡ ΡΠ²Π½ΡΠΉ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡΠΎΡΠ½ΡΠΉ Π΄ΠΎΡΡΡΠΏ (ΠΏΠΎΡΠ΅ΠΌΡ ΠΈ ΠΊΠ°ΠΊ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ ΡΠ΄Π΅Π»Π°Π΅Ρ ΡΡΠΎ, ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎ ΠΎΠΏΠΈΡΠ°Π½ΠΎ Π² Π³Π»Π°Π²Π΅ 5). Π ΡΠ»ΡΡΠ°Π΅ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ², Π΄ΠΎΡΡΡΠΏΠ½ΡΡ Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡΠΎΡΠ½ΠΎΠΉ ΡΡΠ΅Π΄Π΅, Π΄Π»Ρ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΠΏΠΎΠ΄ΡΡΠ΅ΡΠ° ΡΡΡΠ»ΠΎΠΊ ΡΠ»Π΅Π΄ΡΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΏΠΎΠ΄ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Win32 InterlockedIncrement/InterlockedDecrement:
STDMETHODIMP(ULONG) AddRef(void)
{
return InterlockedIncrement(&mcRef);
}
STDMETHODIMP(ULONG) Release(void)
{
LONG res = InterlockedDecrement(&mcRef);
if (res == 0) delete this; return res;
}
ΠΡΠΎΡ ΠΊΠΎΠ΄ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΌΠ΅Π½Π΅Π΅ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π΅Π½, ΡΠ΅ΠΌ Π²Π΅ΡΡΠΈΠΈ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΠΈΠ΅ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΡ C++. ΠΠΎ, Π²ΠΎΠΎΠ±ΡΠ΅ Π³ΠΎΠ²ΠΎΡΡ, ΡΠ°Π·ΡΠΌΠ½Π΅Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΌΠ΅Π½Π΅Π΅ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΡΠ΅ Π²Π°ΡΠΈΠ°Π½ΡΡ InterlockedIncrement / InterlockedDecrement, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎ, ΡΡΠΎ ΠΎΠ½ΠΈ Π½Π°Π΄Π΅ΠΆΠ½Ρ Π²ΠΎ Π²ΡΠ΅Ρ ΡΠΈΡΡΠ°ΡΠΈΡΡ ΠΈ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°ΡΡ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ° ΠΎΡ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ ΡΠΎΡ ΡΠ°Π½ΡΡΡ Π΄Π²Π΅ Π²Π΅ΡΡΠΈΠΈ ΠΏΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°.
ΠΠΎΠΊΠ°Π·Π°Π½Π½ΡΠ΅ Π²ΡΡΠ΅ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ AddRef ΠΈ Release ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°ΡΡ, ΡΡΠΎ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΌΠΎΠΆΠ΅Ρ ΡΠ°Π·ΠΌΠ΅ΡΠ°ΡΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ Π² Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈ ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌΠΎΠΉ ΠΎΠ±Π»Π°ΡΡΠΈ ΠΏΠ°ΠΌΡΡΠΈ (Π² Β«ΠΊΡΡΠ΅Β») Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ Π‘++-ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ° new. Π ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ ΠΊΠ»Π°ΡΡΠ° Π΄Π΅ΡΡΡΡΠΊΡΠΎΡ ΡΠ΄Π΅Π»Π°Π½ Π·Π°ΡΠΈΡΠ΅Π½Π½ΠΎΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠ΅ΠΉ Π΄Π»Ρ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠ΅Π½ΠΈΡ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ Π½ΠΈ ΠΎΠ΄ΠΈΠ½ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ ΠΊΠ»Π°ΡΡΠ° Π½Π΅ Π±ΡΠ» ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ Π½ΠΈΠΊΠ°ΠΊΠΈΠΌ Π΄ΡΡΠ³ΠΈΠΌ ΡΠΏΠΎΡΠΎΠ±ΠΎΠΌ. ΠΠ΄Π½Π°ΠΊΠΎ ΠΈΠ½ΠΎΠ³Π΄Π° ΠΆΠ΅Π»Π°ΡΠ΅Π»ΡΠ½ΠΎ ΠΈΠΌΠ΅ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΡ, Π½Π΅ ΡΠ°Π·ΠΌΠ΅ΡΠ΅Π½Π½ΡΠ΅ Π² Β«ΠΊΡΡΠ΅Β». ΠΠ»Ρ ΡΡΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Π²ΡΠ·ΠΎΠ² delete Π² ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅ΠΌ Π²ΡΠ·ΠΎΠ²Π΅ Release Π±ΡΠ» Π±Ρ Π³ΠΈΠ±Π΅Π»ΡΠ½ΡΠΌ. Π’Π°ΠΊ ΠΊΠ°ΠΊ Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½ΠΎΠΉ ΠΏΡΠΈΡΠΈΠ½ΠΎΠΉ Π΄Π»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΠΎΠ±ΡΠ΅ΠΊΡ Π² ΠΏΠ΅ΡΠ²ΡΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π» ΡΡΠ΅ΡΡΠΈΠΊ ΡΡΡΠ»ΠΎΠΊ, Π±ΡΠ»Π° Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΡ Π²ΡΠ·ΠΎΠ²Π° delete this, Π΄ΠΎΠΏΡΡΡΠΈΠΌΠΎ ΠΎΠΏΡΠΈΠΌΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ ΡΡΠ΅ΡΡΠΈΠΊ ΡΡΡΠ»ΠΎΠΊ Π΄Π»Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ², Π½Π΅ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΡ ΡΡ Π² Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈ ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌΠΎΠΉ ΠΎΠ±Π»Π°ΡΡΠΈ ΠΏΠ°ΠΌΡΡΠΈ:
STDMETHODIMP(ULONG) GlobalVar::AddRef(void)
{
return 2;
// any non-zero value is legal
// Π΄ΠΎΠΏΡΡΡΠΈΠΌΠ° Π»ΡΠ±Π°Ρ Π½Π΅Π½ΡΠ»Π΅Π²Π°Ρ Π²Π΅Π»ΠΈΡΠΈΠ½Π°
}
STDMETHODIMP(ULONG) GlobalVar::Release (void)
{
return 1;
// any non-zero value is legal
// Π΄ΠΎΠΏΡΡΡΠΈΠΌΠ° Π»ΡΠ±Π°Ρ Π½Π΅Π½ΡΠ»Π΅Π²Π°Ρ Π²Π΅Π»ΠΈΡΠΈΠ½Π°
}
ΠΡΠ° ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ ΡΠΎΡ ΡΠ°ΠΊΡ, ΡΡΠΎ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ AddRef ΠΈ Release ΡΠ»ΡΠΆΠ°Ρ ΡΠΎΠ»ΡΠΊΠΎ Π΄Π»Ρ ΡΠ²Π΅Π΄Π΅Π½ΠΈΡ ΠΈ Π½Π΅ ΠΎΠ±ΡΠ·Π°Π½Ρ Π±ΡΡΡ ΡΠΎΡΠ½ΡΠΌΠΈ.
ΠΡΠΈ Π½Π°Π»ΠΈΡΠΈΠΈ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ AddRef ΠΈ Release Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½ΡΠΌ Π΅ΡΠ΅ Π½Π΅ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΡΠΌ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠΌ ΠΈΠ· IUnknown ΠΎΡΡΠ°Π΅ΡΡΡ QueryInterface. ΠΠ³ΠΎ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°ΡΡ ΠΈΠ΅ΡΠ°ΡΡ ΠΈΡ ΡΠΈΠΏΠΎΠ² ΠΎΠ±ΡΠ΅ΠΊΡΠ° ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ΠΈΡ ΡΠΈΠΏΠΎΠ² Π΄Π»Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ° ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΠ³ΠΎ ΡΠΈΠΏΠ° ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π΄Π»Ρ Π²ΡΠ΅Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΠΌΡΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠ². ΠΠ»Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ ΠΊΠ»Π°ΡΡΠ° PugCat, ΡΠ°ΡΡΠΌΠΎΡΡΠ΅Π½Π½ΠΎΠ³ΠΎ ΡΠ°Π½Π΅Π΅, ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΠΊΠΎΠ΄ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎΠΉ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠ΅ΠΉ QueryInterface : STDMETHODIMP
PugCat::QueryInterface(REFIID riid, void **ppv)
{
assert(ppv != 0);
// or return EPOINTER in production
// ΠΈΠ»ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌ EPOINTER Π² ΡΠ΅Π°Π»ΡΠ½ΡΠΉ ΠΏΡΠΎΠ΄ΡΠΊΡ
if (riid == IIDIPug) *ppv = staticcast<IPug*>(this);
else if (riid == IIDIDog) *ppv = staticcast<IDog*>(this);
else if (riid == IIDIAnimal)
// cat or pug?
// ΠΊΠΎΡ ΠΈΠ»ΠΈ ΠΌΠΎΠΏΡ?
*ppv == staticcast<IDog*>(this);
else if (riid == IIDIUnknown)
// cat or pug?
// ΠΊΠΎΡ ΠΈΠ»ΠΈ ΠΌΠΎΠΏΡ?
*ppv = staticcast<IDog*>(this);
else if (riid == IIDICat) *ppv = staticcast<ICat*>(this);
else
{
// unsupported interface
// Π½Π΅ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΠΌΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ
*ppv = 0;
return ENOINTERFACE;
}
// if we reach this point, *ppv is non-null
// and must be AddRef'ed (guideline A2)
// Π΅ΡΠ»ΠΈ ΠΌΡ Π΄ΠΎΡΠ»ΠΈ Π΄ΠΎ ΡΡΠΎΠ³ΠΎ ΠΌΠ΅ΡΡΠ°, ΡΠΎ *ppv Π½Π΅Π½ΡΠ»Π΅Π²ΠΎΠΉ
// ΠΈ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±ΡΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°Π½ AddRef'ΠΎΠΌ ( ΠΏΡΠΈΠ½ΡΠΈΠΏ A2)
reinterpretcast<IUnknown*>(*ppv)->AddRef();
return SOK;
}
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ staticcast Π±ΠΎΠ»Π΅Π΅ ΠΏΡΠ΅Π΄ΠΏΠΎΡΡΠΈΡΠ΅Π»ΡΠ½ΠΎ, ΡΠ΅ΠΌ ΡΡΠ°Π΄ΠΈΡΠΈΠΎΠ½Π½ΡΠ΅ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ΠΈΡ ΡΠΈΠΏΠ° Π² ΡΡΠΈΠ»Π΅ Π‘:
*ppv = (IPug*)this;
ΡΠ°ΠΊ ΠΊΠ°ΠΊ Π²Π°ΡΠΈΠ°Π½Ρ staticcast Π²ΡΠ·ΠΎΠ²Π΅Ρ ΠΎΡΠΈΠ±ΠΊΡ ΡΡΠ°ΠΏΠ° ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ, Π΅ΡΠ»ΠΈ ΠΏΡΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½Π½ΠΎΠ΅ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΡΠΈΠΏΠ° Π½Π΅ ΡΠΎΠ³Π»Π°ΡΡΠ΅ΡΡΡ Ρ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠΈΠΌ Π±Π°Π·ΠΎΠ²ΡΠΌ ΠΊΠ»Π°ΡΡΠΎΠΌ.
ΠΠ°ΠΌΠ΅ΡΠΈΠΌ, ΡΡΠΎ Π² ΠΏΠΎΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ Π·Π΄Π΅ΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ QueryInterface ΠΏΡΠΈ Π·Π°ΠΏΡΠΎΡΠ΅ Π½Π° ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ, ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡΠΈΠΉΡΡ Π±ΠΎΠ»Π΅Π΅ ΡΠ΅ΠΌ ΠΎΠ΄Π½ΠΈΠΌ Π±Π°Π·ΠΎΠ²ΡΠΌ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠΌ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, IUnknown, IAnimal) ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΡΠΈΠΏΠ° Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΡΠ²Π½ΠΎ Π²ΡΠ±ΡΠ°ΡΡ Π±ΠΎΠ»Π΅Π΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠΉ Π±Π°Π·ΠΎΠ²ΡΠΉ ΠΊΠ»Π°ΡΡ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π΄Π»Ρ ΠΊΠ»Π°ΡΡΠ° PugCat ΡΠ°ΠΊΠΎΠΉ Π²ΠΏΠΎΠ»Π½Π΅ Π±Π΅Π·ΠΎΠ±ΠΈΠ΄Π½ΠΎ Π²ΡΠ³Π»ΡΠ΄ΡΡΠΈΠΉ ΠΊΠΎΠ΄ Π½Π΅ ΠΎΡΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΡΠ΅ΡΡΡ:
if (riid == IIDIUnknown) *ppv = staticcast<IUnknown*>(this);
ΠΡΠΎΡ ΠΊΠΎΠ΄ Π½Π΅ ΠΏΡΠΎΠΉΠ΄Π΅Ρ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΡ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΠ°ΠΊΠΎΠ΅ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΡΠΈΠΏΠ° ΡΠ²Π»ΡΠ΅ΡΡΡ Π½Π΅ΠΎΠ΄Π½ΠΎΠ·Π½Π°ΡΠ½ΡΠΌ ΠΈ ΠΌΠΎΠΆΠ΅Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΎΠ²Π°ΡΡ Π±ΠΎΠ»Π΅Π΅ ΡΠ΅ΠΌ ΠΎΠ΄Π½ΠΎΠΌΡ Π±Π°Π·ΠΎΠ²ΠΎΠΌΡ ΠΊΠ»Π°ΡΡΡ. ΠΡΠΎ Π±ΡΠ»ΠΎ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² ΡΠ»ΡΡΠ°Π΅ FastString ΠΈ IExtensibleObject ΠΈΠ· ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅ΠΉ Π³Π»Π°Π²Ρ. ΠΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ Π΄ΠΎΠ»ΠΆΠ½Π° Π±ΠΎΠ»Π΅Π΅ ΡΠΎΡΠ½ΠΎ Π²ΡΠ±ΡΠ°ΡΡ ΡΠΈΠΏ Π΄Π»Ρ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ΠΈΡ:
if (riid == IIDIUnknown) ppv = staticcast<IDog*>(this);
ΠΈΠ»ΠΈ if (riid == IIDIUnknown) ppv = staticcast<ICat*>(this);
ΠΠ°ΠΆΠ΄ΡΠΉ ΠΈΠ· ΡΡΠΈΡ Π΄Π²ΡΡ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΠΎΠ² ΠΊΠΎΠ΄Π° Π΄ΠΎΠΏΡΡΡΠΈΠΌ Π΄Π»Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ PugCat. ΠΠ΅ΡΠ²ΡΠΉ Π²Π°ΡΠΈΠ°Π½Ρ ΠΏΡΠ΅Π΄ΠΏΠΎΡΡΠΈΡΠ΅Π»ΡΠ½Π΅Π΅, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΌΠ½ΠΎΠ³ΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΡ Π²ΡΠ΄Π°ΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π±ΠΎΠ»Π΅Π΅ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΡΠΉ ΠΊΠΎΠ΄, ΠΊΠΎΠ³Π΄Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ ΠΊΡΠ°ΠΉΠ½ΠΈΠΉ Π»Π΅Π²ΡΠΉ Π±Π°Π·ΠΎΠ²ΡΠΉ ΠΊΠ»Π°ΡΡ[1].
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° Π‘ΠΠ
ΠΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΡΡ C++ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄Ρ IUnknown ΡΠ²Π½ΠΎ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ ΠΌΠΎΠ΄Π΅Π»ΠΈ Π‘ΠΠ Π½Π° ΡΠ·ΡΠΊ C++ Π½Π΅ ΠΏΡΠ΅Π΄ΡΡΠΌΠ°ΡΡΠΈΠ²Π°Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΡΡΠ΅Π΄Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΈ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ (runtime layer) ΠΌΠ΅ΠΆΠ΄Ρ ΠΊΠΎΠ΄ΠΎΠΌ ΠΊΠ»ΠΈΠ΅Π½ΡΠ° ΠΈ ΠΊΠΎΠ΄ΠΎΠΌ ΠΎΠ±ΡΠ΅ΠΊΡΠ°. ΠΠΎΡΡΠΎΠΌΡ IUnknown ΠΌΠΎΠΆΠ½ΠΎ ΡΠ°ΡΡΠΌΠ°ΡΡΠΈΠ²Π°ΡΡ ΠΏΡΠΎΡΡΠΎ ΠΊΠ°ΠΊ Π½Π°Π±ΠΎΡ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΠΉ, ΠΊΠΎΡΠΎΡΡΠ΅ Π²ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΡΡ Π‘ΠΠ Π΄Π°ΡΡ Π΄ΡΡΠ³ Π΄ΡΡΠ³Ρ. ΠΡΠΎ Π΄Π°Π΅Ρ ΠΏΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ²ΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΡΠ°ΠΌ C++, ΡΠ°ΠΊ ΠΊΠ°ΠΊ C++ ΠΌΠΎΠΆΠ΅Ρ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΠΊΠΎΠ΄, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠΎΡΠ΅Π½ΡΠΈΠ°Π»ΡΠ½ΠΎ Π±ΠΎΠ»Π΅Π΅ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π΅Π½, ΡΠ΅ΠΌ ΡΠ·ΡΠΊΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ ΡΡΠ΅Π±ΡΡΡ ΡΠ°ΠΊΠΎΠ³ΠΎ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΡΠ»ΠΎΡ ΠΏΡΠΈ ΡΠ°Π±ΠΎΡΠ΅ Ρ Π‘ΠΠ.