Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π‘ΡƒΡ‰Π½ΠΎΡΡ‚ΡŒ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ БОМ. Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 18

Автор Π”ΠΎΠ½Π°Π»ΡŒΠ΄ Бокс

{

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++ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ Π±ΠΎΠ»Π΅Π΅ эффСктивСн, Ρ‡Π΅ΠΌ языки, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ Ρ‚Π°ΠΊΠΎΠ³ΠΎ динамичСского слоя ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с БОМ.