ΠŸΠΎΠΌΠΎΡ‰ΡŒ Π² ΡƒΡ‡Ρ‘Π±Π΅, ΠΎΡ‡Π΅Π½ΡŒ быстро...
Π Π°Π±ΠΎΡ‚Π°Π΅ΠΌ вмСстС Π΄ΠΎ ΠΏΠΎΠ±Π΅Π΄Ρ‹

РаспрСдСлСнная ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ…

ΠšΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½Π°ΡΠŸΠΎΠΌΠΎΡ‰ΡŒ Π² Π½Π°ΠΏΠΈΡΠ°Π½ΠΈΠΈΠ£Π·Π½Π°Ρ‚ΡŒ ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒΠΌΠΎΠ΅ΠΉ Ρ€Π°Π±ΠΎΡ‚Ρ‹

IX ΠΈ IY — это чисто абстрактныС Π±Π°Π·ΠΎΠ²Ρ‹Π΅ классы, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ интСрфСйсов. Чистоабстрактный Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ класс (pure abstract base class) — это Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ класс, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ содСрТит Ρ‚ΠΎΠ»ΡŒΠΊΠΎ чисто Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ (pure virtual functions). Чисто Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Π°Ρ функция — это Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Π°Ρ функция, «ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Π½Π°Ρ =0 — Π·Π½Π°ΠΊΠΎΠΌ спСцификатора чистоты (pure specifier). Чисто Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ… Π§ΠΈΡ‚Π°Ρ‚ΡŒ Π΅Ρ‰Ρ‘ >

РаспрСдСлСнная ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ… (Ρ€Π΅Ρ„Π΅Ρ€Π°Ρ‚, курсовая, Π΄ΠΈΠΏΠ»ΠΎΠΌ, ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½Π°Ρ)

  • Π—Π°Π΄Π°Π½ΠΈΠ΅ № 1 РСализация интСрфСйса COM
    • Π—Π°Π΄Π°Π½ΠΈΠ΅ № 1А QueryInterface
    • Π—Π°Π΄Π°Π½ΠΈΠ΅ № 1B ΠŸΠΎΠ΄ΡΡ‡Π΅Ρ‚ ссылок

Π—Π°Π΄Π°Π½ΠΈΠ΅ № 1 РСализация интСрфСйса COM

ЦСль Ρ€Π°Π±ΠΎΡ‚Ρ‹:

Π Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΊΠΎΠ΄ Π½Π° Π‘++, Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‰ΠΈΠΉ простой интСрфСйс БОМ Π±Π΅Π· динамичСской ΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²ΠΊΠΈ:

ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‚ Ρ‡Π΅Ρ€Π΅Π· Π΄Π²Π° интСрфСйса IX ΠΈIY, интСрфСйсы COM Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ‹ ΠΊΠ°ΠΊ чисто абстрактныС Π±Π°Π·ΠΎΠ²Ρ‹Π΅ классы Π‘++;

Π² ΠΊΠ°Ρ‡Π΅ΡΡ‚Π²Π΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρƒ main;

ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ рСализуСтся классом БА, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ наслСдуСт ΠΊΠ°ΠΊ IX Ρ‚Π°ΠΊ ΠΈ IY;

класс Π‘А Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Ρ‹ ΠΎΠ±ΠΎΠΈΡ… интСрфСйсов (мноТСствСнноС наслСдованиС);

ΠΊΠ»ΠΈΠ΅Π½Ρ‚ создаСт экзСмпляр ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° (для управлСния сущСствованиСм ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ примСняСт ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° new ΠΈ delete), Π΄Π°Π»Π΅Π΅ ΠΎΠ½ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° ΠΈΠ½Ρ‚СрфСйсы, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Π΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠΌ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ эти ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π°Π½ΠΎΠ»ΠΎΠ³ΠΈΡ‡Π½ΠΎ указатСлям Π½Π° ΠΊΠ»Π°ΡΡΡ‹ Π‘++;

Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΡ‡Π½Ρ‹Π΅ сообщСния ΠΏΡ€ΠΈ использовании интСрфСйсов IX ΠΈ IY;

ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚;

вмСсто опрСдСлСния интСрфСйса ΠΊΠ°ΠΊ класса ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΈΠ· Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° OBJBASE. H

#define interface struct

ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Ρ‹ ΠΎΠ±ΡŠΡΠ²Π»ΡΡ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ

virtual void _stdcall … .

ВСорСтичСскиС свСдСния:

Π’ Π‘ОМ интСрфСйсы — это всС. Для ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ прСдставляСт собой Π½Π°Π±ΠΎΡ€ интСрфСйсов. ΠšΠ»ΠΈΠ΅Π½Ρ‚ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ с ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠΌ БОМ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Π΅Ρ€Π΅Π· интСрфСйс. Π‘ Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния программиста БОМ, интСрфСйсы — ваТная Ρ‡Π°ΡΡ‚ΡŒ любого прилоТСния. ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ сами ΠΏΠΎ ΡΠ΅Π±Π΅ Π΅ΡΡ‚ΡŒ просто Π΄Π΅Ρ‚Π°Π»ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ интСрфСйсов.

Π£Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ — всСго лишь Π΄Π΅Ρ‚Π°Π»ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ интСрфСйса, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, ΠΏΡ€Π΅ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅. Π’ ΠΊΠΎΠ½Ρ†Π΅ ΠΊΠΎΠ½Ρ†ΠΎΠ², интСрфСйс Π±Π΅Π· Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ ΡΠ΄Π΅Π»Π°Π΅Ρ‚. Однако ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ ΠΈ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΠΌ; Ссли Π½ΠΎΠ²Ρ‹ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Ρ‚Π΅ ΠΆΠ΅ ΠΈΠ½Ρ‚СрфСйсы, Ρ‡Ρ‚ΠΎ ΠΈ ΡΡ‚Π°Ρ€Ρ‹ΠΉ, ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΏΠΎ-ΠΏΡ€Π΅ΠΆΠ½Π΅ΠΌΡƒ. ΠžΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ сами ΠΏΠΎ ΡΠ΅Π±Π΅ Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ прилоТСния. ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ интСрфСйсы ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°ΠΌΠΈ. Пока интСрфСйсы Π½Π΅ΠΈΠ·ΠΌΠ΅Π½Π½Ρ‹, ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎΡΠ²Π»ΡΡ‚ΡŒΡΡ ΠΈ ΠΈΡΡ‡Π΅Π·Π°Ρ‚ΡŒ

Π’Π΅ΠΏΠ΅Ρ€ΡŒ рассмотрим ΠΊΠΎΠ΄, Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‰ΠΈΠΉ простой интСрфСйс. Π’ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌ Π½ΠΈΠΆΠ΅ тСкстС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ CA ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ IX ΠΈ IY для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π΄Π²ΡƒΡ… интСрфСйсов.

class IX // ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ интСрфСйс

{

public:

virtual void Fx1() = 0;

virtual void Fx2() = 0;

};

class IY // Π’Ρ‚ΠΎΡ€ΠΎΠΉ интСрфСйс

{

public:

virtual void Fy1() = 0;

virtual void Fy2() = 0;

};

class CA: public IX, public IY // ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚

{

public:

// РСализация абстрактного Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса IX

virtual void Fx1() { cout << «Fx1» << endl; }

virtual void Fx2() { cout << «Fx2» << endl; }

// РСализация абстрактного Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса IY

virtual void Fy1() { cout << «Fy1» << endl; }

virtual void Fy2() { cout << «Fy2» << endl; }

};

IX ΠΈ IY — это чисто абстрактныС Π±Π°Π·ΠΎΠ²Ρ‹Π΅ классы, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ интСрфСйсов. Чистоабстрактный Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ класс (pure abstract base class) — это Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ класс, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ содСрТит Ρ‚ΠΎΠ»ΡŒΠΊΠΎ чисто Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ (pure virtual functions). Чисто Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Π°Ρ функция — это Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Π°Ρ функция, «ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Π½Π°Ρ =0 — Π·Π½Π°ΠΊΠΎΠΌ спСцификатора чистоты (pure specifier). Чисто Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π΅ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‚сяв классах, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Ρ‹. Как Π²ΠΈΠ΄Π½ΠΎ ΠΈΠ· ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠ³ΠΎ Π²Ρ‹ΡˆΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ IX: Fx1, IX: Fx2, IY: Fy1 ΠΈ IY: Fy2 Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π΄Π΅ΠΊΠ»Π°Ρ€ΠΈΡ€ΡƒΡŽΡ‚ΡΡ. Π Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‚ΡΡ ΠΆΠ΅ ΠΎΠ½ΠΈ Π² ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΠΎΠΌ классС. Π’ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π΅ ΠΊΠΎΠ΄Π° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ CA наслСдуСт Π΄Π²Π° чисто абстрактных Π±Π°Π·ΠΎΠ²Ρ‹Ρ… класса — IX ΠΈ IY — ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ ΠΈΡ… Ρ‡ΠΈΡΡ‚ΠΎ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

Для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Ρ‹ IX ΠΈ IY, CA ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ мноТСствСнноС наслСдованиС. ПослСднСС ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ класс являСтся ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½Ρ‹ΠΌ Π±ΠΎΠ»Π΅Π΅ Ρ‡Π΅ΠΌ ΠΎΡ‚ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса. Класс Π‘++ Ρ‡Π°Ρ‰Π΅ всСго ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π΅Π΄ΠΈΠ½ΠΈΡ‡Π½ΠΎΠ΅ наслСдованиС, Ρ‚. Π΅. ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ класс.

ВСкст ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹:

#include «stdafx.h»

#include «iostream.h»

#include «objbase.h» // ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ интСрфСйс

#include «conio.h»

void trace (const char* pMsg) { cout << pMsg << endl; }

// АбстрактныС интСрфСйсы

interface IX

{

virtual void __stdcall Fx1() = 0;

virtual void __stdcall Fx2() = 0;

};

interface IY

{

virtual void __stdcall Fy1() = 0;

virtual void __stdcall Fy2() = 0;

};

// РСализация интСрфСйса

class CA: public IX,

public IY

{

public:

// РСализация интСрфСйса IX

virtual void __stdcall Fx1() { cout << «CA:Fx1» << endl; }

virtual void __stdcall Fx2() { cout << «CA:Fx2» << endl; }

// РСализация интСрфСйса IY

virtual void __stdcall Fy1() { cout << «CA:Fy1» << endl; }

virtual void __stdcall Fy2() { cout << «CA:Fy2» << endl; }

};

// ΠšΠ»ΠΈΠ΅Π½Ρ‚

int main ()

{

trace («Client: Sozdanie ekzemplyra komponenta»);

CA* pA = new CA;

// ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ IX

IX* pIX = pA;

trace («Client: Ispol’zovanie interface IX»);

pIX->Fx1();

pIX->Fx2();

// ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ IY

IY* pIY = pA;

trace («Client: Ispol’zovanie interface IY»);

pIY->Fy1();

pIY->Fy2();

trace («Client: Delete komponent»);

delete pA;

getch ();

return 0; }

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹:

Π’Ρ‹Π²ΠΎΠ΄:

Π’ Π΄Π°Π½Π½ΠΎΠΌ Π·Π°Π΄Π°Π½ΠΈΠΈ ΠΌΡ‹ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²ΠΎΠ²Π°Π»ΠΈ простой интСрфСйс БОМ Π±Π΅Π· динамичСской ΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²ΠΊΠΈ. Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡΡ‹ COM Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ‹ ΠΊΠ°ΠΊ чисто абстрактныС Π±Π°Π·ΠΎΠ²Ρ‹Π΅ классы Π‘++, Π² ΠΊΠ°Ρ‡Π΅ΡΡ‚Π²Π΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° использовали ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρƒ main.

Π—Π°Π΄Π°Π½ΠΈΠ΅ 2 № 1А QueryInterface

ЦСль Ρ€Π°Π±ΠΎΡ‚Ρ‹:

ΠžΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ интСрфСйсы IX, IY, IZ. ΠžΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ интСрфСйс IUnknown.

РСализация ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°. Класс БА Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉ интСрфСйсы IX ΠΈ IY. Π Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ QueryInterface описанным Π²Ρ‹ΡˆΠ΅ способом. Π€ΡƒΠ½ΠΊΡ†ΠΈΡŽ CreateInstance ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ послС класса CA. ΠšΠ»ΠΈΠ΅Π½Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π΅Π΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚, прСдставляСмый ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ БА, ΠΈ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° IUnknown этого ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°. ПослС CreateInstance ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ IID для интСрфСйсов. (Для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ IID для IUnknown ΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²Π°Ρ‚ΡŒ с UUID. LIB).

РСализация ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, Ρ€ΠΎΠ»ΡŒ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ выполняСт main. ΠšΠ»ΠΈΠ΅Π½Ρ‚ Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚ с ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ CreateInstance. CreateInstance Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΈΠ½Ρ‚СрфСйс IUnknown ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°. ΠšΠ»ΠΈΠ΅Π½Ρ‚ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ QueryInterface Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ Ρ‡Π΅Ρ€Π΅Π· интСрфСйс IUnknown ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΈΠ½Ρ‚СрфСйс IX ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°. Анологично Π·Π°ΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ ΠΈ IY. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ эти ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ для доступа ΠΊ Ρ„ункциям-Ρ‡Π»Π΅Π½Π°ΠΌ. Π—Π°ΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ интСрфСйс IZ. QueryInterface Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΊΠΎΠ΄ ошибки, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π‘А Π½Π΅ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ IZ. Π”Π°Π»Π΅Π΅ ΠšΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΈΠ½Ρ‚СрфСйс IY Ρ‡Π΅Ρ€Π΅Π· ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΈΠ½Ρ‚СрфСйс IX, pIX. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ IY, этот запрос Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΡΠΏΠ΅ΡˆΠ½Ρ‹ΠΌ, ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ смоТСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½Π½Ρ‹ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΈΠ½Ρ‚СрфСйс IY Ρ‚Π°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ΠΎΠ½ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π» ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ. Π—Π°Ρ‚Π΅ΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ интСрфСйс IUnknown Ρ‡Π΅Ρ€Π΅Π· ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° IY. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ всС интСрфСйсы COM Π½Π°ΡΠ»Π΅Π΄ΡƒΡŽΡ‚ IUnknown, этот запрос Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΡƒΡΠΏΠ΅ΡˆΠ½Ρ‹ΠΌ, ΠΏΡ€ΠΈΡ‡Π΅ΠΌ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½Π½Ρ‹ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ совпадСт с ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ. QueryInterface Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Π²ΡΠ΅ запросы ΠΊ IUnknown.

ВСорСтичСскиС свСдСния:

Π’ COM ΠΊΠ»ΠΈΠ΅Π½Ρ‚ взаимодСйствуСт с ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠΌ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ интСрфСйса

IUnknown, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅ UNKWN. H:

Interface IUnknown

{

virtual HREZULT —stdcall QueryInterface (const IID&iid,

void * * ppv) = 0 ;

virtual ULONG —stdcall Addref () = 0 ;

virtual ULONG —stdcall Release () = 0 ;

};

Π€ΡƒΠ½ΠΊΡ†ΠΈΡŽ с ΠΈΠΌΠ΅Π½Π΅ΠΌ QueryInterface ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Π»ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ интСрфСйс. Π£ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ QueryInterface Π΄Π²Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°. ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ — ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ интСрфСйса. Π’Ρ‚ΠΎΡ€ΠΎΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ — адрСс, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ QueryInterface ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΈΡΠΊΠΎΠΌΡ‹ΠΉ интСрфСйс.

QueryInterface Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ HREZULT — 32-разрядный ΠΊΠΎΠ΄ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°.

QueryInterface ΠΌΠΎΠΆΠ΅Ρ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ Π»ΠΈΠ±ΠΎ S_OK, Π»ΠΈΠ±ΠΎ E_NOINTERFACE. ΠšΠ»ΠΈΠ΅Π½Ρ‚ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ прямо ΡΡ€Π°Π²Π½ΠΈΠ²Π°Ρ‚ΡŒ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ QueryInterface Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ с ΡΡ‚ΠΈΠΌΠΈ константами; для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π½Π°Π΄ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ макросы SUCCEEDED ΠΈΠ»ΠΈ FAILED.

ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ указатСля Π½Π° IUnknown

Для получСния указатСля Π½Π° IUnknown ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, CreateInstance которая создаСт ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° IUnknown:

IUnknown * CreateInstance ()

РСализация Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ CreateInstance:

IUnknown * pI = static_cast (new CA) ;

PI->Addref () ;

Return pI ;

ИспользованиС QueryInterface.

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Ρ‚ΠΎ Ρƒ Π½Π°Ρ Π΅ΡΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° IUnknown, pI. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ, ΠΌΠΎΠΆΠ½ΠΎ Π»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π΄Ρ€ΡƒΠ³ΠΎΠΉ интСрфСйс, ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ QueryInterface, пСрСдавая Π΅ΠΉ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ Π½ΡƒΠΆΠ½ΠΎΠ³ΠΎ Π½Π°ΠΌ интСрфСйса. Если QueryInterface ΠΎΡ‚Ρ€Π°Π±ΠΎΡ‚Π°Π»Π° ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ:

void foo (IUnknown* pI)

{

// ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΈΠ½Ρ‚СрфСйс

IX* pIX=NULL;

// Π—Π°ΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ интСрфСйс IX

HREZULT hr = pI-> QueryInterface (IID_IX, (void**)&pIX) ;

// ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°

if (SUCCEEDED (hr))

{

// Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ интСрфСйс

pIXFx () ;

}

}

РСализация QueryInterface.

Π—Π°ΠΏΠΈΡˆΠ΅ΠΌ QueryInterface для ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°, Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅ΠΌΠΎΠ³ΠΎ классом CA:

Interface IX: IUnknown { /*…*/ } ;

Interface IY: IUnknown { /*…*/ } ;

Class CA: public IX, public IY { /*…*/ } ;

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠ΄Π° Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ QueryInterface для класса, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠ³ΠΎ Π²Ρ‹ΡˆΠ΅ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π° ΠΊΠΎΠ΄Π°.

HREZULT —stdcall CA: QueryInterface (const IID&iid, void * * ppv);

{

if (iid ==IID_IUnknown)

{

// ΠšΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ интСрфСйс IUnknown

*ppv = static_cast (this) ;

}

else if (iid ==IID_IX)

{

// ΠšΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ интСрфСйс IX

*ppv = static_cast (this) ;

}

else if (iid ==IID_IY)

{

// ΠšΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ интСрфСйс IY

*ppv = static_cast (this) ;

}

else

{

// ΠœΡ‹ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ интСрфСйс.

// Π£ΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π² NULL.

*ppv = NULL ;

return E_NOINTERFACE ;

}

static_cast< IUnknown*>(*ppv)->AddRef () ;

return S_OK ;

}

ВСкст ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹:

#include «stdafx.h»

#include «iostream.h»

#include «objbase.h»

#include «conio.h»

void trace (const char* msg) { cout << msg << endl; }

// Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡΡ‹

interface IX: IUnknown

{

virtual void __stdcall Fx () = 0;

};

interface IY: IUnknown

{

virtual void __stdcall Fy () = 0;

};

interface IZ: IUnknown

{

virtual void __stdcall Fz () = 0;

};

// ΠŸΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ объявлСния GUID

extern const IID IID_IX;

extern const IID IID_IY;

extern const IID IID_IZ;

// ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚

class CA: public IX, public IY

{

// РСализация IUnknown

virtual HRESULT __stdcall QueryInterface (const IID& iid, void** ppv);

virtual ULONG __stdcall AddRef () { return 0; }

virtual ULONG __stdcall Release () { return 0; }

// РСализация интСрфСйса IX

virtual void __stdcall Fx () { cout << «Fx» << endl; }

// РСализация интСрфСйса IY

virtual void __stdcall Fy () { cout << «Fy» << endl; }

};

HRESULT __stdcall CA: QueryInterface (const IID& iid, void** ppv)

{

if (iid == IID_IUnknown)

{

trace («QueryInterface: Vernyt' ykazatel' na IUnknown»);

*ppv = static_cast (this);

}

else if (iid == IID_IX)

{

trace («QueryInterface: Vernyt' ykazatel' na IX»);

*ppv = static_cast (this);

}

else if (iid == IID_IY)

{

trace («QueryInterface: Vernyt' ykazatel' na IY»);

*ppv = static_cast (this);

}

else

{

trace («QueryInterface: Interface No!»);

*ppv = NULL;

return E_NOINTERFACE;

}

reinterpret_cast (*ppv)->AddRef ();

return S_OK;

}

// Ѐункция создания

IUnknown* CreateInstance ()

{

IUnknown* pI = static_cast (new CA);

pI->AddRef ();

return pI;

}

// IID

// {32bb8320-b41b-11cf-a6bb-0080c7b2d682}

static const IID IID_IX =

{0×32bb8320, 0xb41b, 0×11cf,

{0xa6, 0xbb, 0×0, 0×80, 0xc7, 0xb2, 0xd6, 0×82}};

// {32bb8321-b41b-11cf-a6bb-0080c7b2d682}

static const IID IID_IY =

{0×32bb8321, 0xb41b, 0×11cf,

{0xa6, 0xbb, 0×0, 0×80, 0xc7, 0xb2, 0xd6, 0×82}};

// {32bb8322-b41b-11cf-a6bb-0080c7b2d682}

static const IID IID_IZ =

{0×32bb8322, 0xb41b, 0×11cf,

{0xa6, 0xbb, 0×0, 0×80, 0xc7, 0xb2, 0xd6, 0×82}};

// ΠšΠ»ΠΈΠ΅Π½Ρ‚

int main ()

{

HRESULT hr;

trace («Client: Polychit' ykazatel' na IUnknown»);

IUnknown* pIUnknown = CreateInstance ();

trace («Client: Polychit' ykazatel' na IX»);

IX* pIX = NULL;

hr = pIUnknown->QueryInterface (IID_IX, (void**)&pIX);

if (SUCCEEDED (hr))

{

trace («Client: IX polychen»);

pIX->Fx (); // Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ интСрфСйс IX

}

trace («Client: Polychit' ykazatel na IY»);

IY* pIY = NULL;

hr = pIUnknown->QueryInterface (IID_IY, (void**)&pIY);

if (SUCCEEDED (hr))

{

trace («Client: IY polychen»);

pIY->Fy (); // Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ интСрфСйс IY

}

trace («Client: Zaprosit' nepodderjivaemuy interface»);

IZ* pIZ = NULL;

hr = pIUnknown->QueryInterface (IID_IZ, (void**)&pIZ);

if (SUCCEEDED (hr))

{

trace («Client: Interface IZ polychen»);

pIZ->Fz ();

}

else

{

trace («Client: No Interface IZ»);

}

trace («Client: Polychit' Interface IY cherez Interface IX»);

IY* pIYfromIX = NULL;

hr = pIX->QueryInterface (IID_IY, (void**)&pIYfromIX);

if (SUCCEEDED (hr))

{

trace («Client: IY polychen»);

pIYfromIX->Fy ();

}

trace («Client: Polechit' Interface IUnknown cherez IY»);

IUnknown* pIUnknownFromIY = NULL;

hr = pIY->QueryInterface (IID_IUnknown, (void**)&pIUnknownFromIY);

if (SUCCEEDED (hr))

{

cout << «Sovpadaut li ykazateli na IUnknown? «;

if (pIUnknownFromIY == pIUnknown)

{

cout << «Yes, pIUnknownFromIY == pIUnknown» << endl;

}

else

{

cout << «No, pIUnknownFromIY ≠ pIUnknown» << endl;

}

}

// Π£Π΄Π°Π»ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚

delete pIUnknown;

getch ();

return 0;

}

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹:

Π’Ρ‹Π²ΠΎΠ΄:

Π’ Π΄Π°Π½Π½ΠΎΠΌ Π·Π°Π΄Π°Π½ΠΈΠΈ объявили интСрфСйсы IX, IY, IZ, ΠΈ ΠΈΠ½Ρ‚СрфСйс IUnknown.

Π Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π»ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚. Класс БА ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉ интСрфСйсы IX ΠΈ IY. Π Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π»ΠΈ QueryInterface. Π€ΡƒΠ½ΠΊΡ†ΠΈΡŽ CreateInstance, которая опрСдСляСтся послС класса CA. ΠšΠ»ΠΈΠ΅Π½Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π΅Π΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚, прСдставляСмый ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ БА, ΠΈ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° IUnknown этого ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°.

Π—Π°Π΄Π°Π½ΠΈΠ΅ № 1B ΠŸΠΎΠ΄ΡΡ‡Π΅Ρ‚ ссылок

ЦСль Ρ€Π°Π±ΠΎΡ‚Ρ‹:

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ ΠΈΠ· Π»Π°Π±ΠΎΡ€ΠΎΡ‚ΠΎΡ€Π½ΠΎΠΉ Ρ€Π°Π±ΠΎΡ‚Ρ‹ № 1А подсчСт ссылок. Для этого ΠΊ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρƒ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π΄Π²ΡƒΡ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² IUnknown — AddRef ΠΈ Release. ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Win32 InterlockedIncrement ΠΈ InterlockedDecrement. Π€ΡƒΠ½ΠΊΡ†ΠΈΡŽ AddRef Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ CreateInstance ΠΈ QueryInterface для ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π° ΠΈΠ½Ρ‚СрфСйсы. Π’Ρ‹Π·ΠΎΠ²Ρ‹ Release Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π² ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡ΠΈΡ‚ΡŒ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΠ΅ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ интСрфСйсами.

Π›ΠΈΠΊΠ²ΠΈΠ΄ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ дСструктора.

ВСорСтичСскиС свСдСния:

ВмСсто Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ, ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΡΠΎΠΎΠ±Ρ‰Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρƒ, Ρ‡Ρ‚ΠΎ Π½Π°ΠΌ Π½ΡƒΠΆΠ΅Π½ интСрфСйс ΠΈΠ»ΠΈ Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΠ»ΠΈ с Π½ΠΈΠΌ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ. ΠœΡ‹ Ρ‚ΠΎΡ‡Π½ΠΎ Π·Π½Π°Π΅ΠΌ, ΠΊΠΎΠ³Π΄Π° Π½Π°Ρ‡ΠΈΠ½Π°Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ интСрфСйс, ΠΈ Π·Π½Π°Π΅ΠΌ (ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ), ΠΊΠΎΠ³Π΄Π° пСрСстаСм Π΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ. Однако, ΠΊΠ°ΠΊ ΡƒΠΆΠ΅ ясно, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π½Π΅ Π·Π½Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π²ΠΎΠΎΠ±Ρ‰Π΅. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΈΠΌΠ΅Π΅Ρ‚ смысл ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚ΡŒΡΡ сообщСниСм ΠΎΠ± ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π΄Π°Π½Π½Ρ‹ΠΌ интСрфСйсом — ΠΈ ΠΏΡƒΡΡ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ сам отслСТиваСт, ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅ΡΡ‚Π°Π΅ΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ всСми интСрфСйсами.

ИмСнно для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ этой стратСгии ΠΈ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Ρ‹ Π΅Ρ‰Π΅ Π΄Π²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Π° IUnknown — AddRef ΠΈ Release.

ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ интСрфСйса IUnknown:

interface IUnknown

{

virtual HRESULT __stdcall QueryInterface (const IID& iid, void** ppv) = 0;

virtual ULONG __stdcall AddRef () = 0;

virtual ULONG __stdcall Release () = 0;

};

AddRef ΠΈ Release Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‚ ΠΈ Ρ‚Π΅Ρ…Π½ΠΈΠΊΡƒ управлСния ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ, ΠΈΠ·Π²Π΅ΡΡ‚Π½ΡƒΡŽ ΠΊΠ°ΠΊ подсчСт ссылок (reference counting).

ΠŸΠΎΠ΄ΡΡ‡Π΅Ρ‚ ссылок — простой ΠΈ Π±Ρ‹ΡΡ‚Ρ€Ρ‹ΠΉ способ, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°ΠΌ самим ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ сСбя. ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ БОМ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ счСтчик ссылок. Когда ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ интСрфСйс, Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ этого счСтчика увСличиваСтся Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ. Когда ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°ΠΊΠ°Π½Ρ‡ΠΈΠ²Π°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ с ΠΈΠ½Ρ‚СрфСйсом, Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ΡΡ. Когда ΠΎΠ½ΠΎ Π΄ΠΎΡ…ΠΎΠ΄ΠΈΡ‚ Π΄ΠΎ Π½ΡƒΠ»Ρ, ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ удаляСт сСбя ΠΈΠ· ΠΏΠ°ΠΌΡΡ‚ΠΈ. ΠšΠ»ΠΈΠ΅Π½Ρ‚ Ρ‚Π°ΠΊΠΆΠ΅ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ счСтчик ссылок, ΠΊΠΎΠ³Π΄Π° создаСт Π½ΠΎΠ²ΡƒΡŽ ссылку Π½Π° ΡƒΠΆΠ΅ ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΠΉΡΡ Ρƒ Π½Π΅Π³ΠΎ интСрфСйс. Как Π’Ρ‹, вСроятно, догадались, увСличиваСтся счСтчик Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ AddRef, Π° ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ся — Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ Release.

Для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ подсчСтом ссылок, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π·Π½Π°Ρ‚ΡŒ лишь Ρ‚Ρ€ΠΈ простых ΠΏΡ€Π°Π²ΠΈΠ»Π°:

1. Π’Ρ‹Π·Ρ‹Π²Π°ΠΉΡ‚Π΅ AddRef ΠΏΠ΅Ρ€Π΅Π΄ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΎΠΌ. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰ΠΈΠ΅ интСрфСйсы, ΠΏΠ΅Ρ€Π΅Π΄ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΎΠΌ всСгда

Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ AddRef для ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ указатСля. Π­Ρ‚ΠΎ Ρ‚Π°ΠΊΠΆΠ΅ относится ΠΊ QueryInterface ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ CreateInstance. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Π’Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ AddRef Π² ΡΠ²ΠΎΠ΅ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ послС получСния (ΠΎΡ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ) указатСля Π½Π° ΠΈΠ½Ρ‚СрфСйс.

2. По Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π²Ρ‹Π·Ρ‹Π²Π°ΠΉΡ‚Π΅ Release. Когда Π’Ρ‹ Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΠ»ΠΈ Ρ€Π°Π±ΠΎΡ‚Ρƒ с ΠΈΠ½Ρ‚СрфСйсом, слСдуСт Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ для Π½Π΅Π³ΠΎ Release.

3. Π’Ρ‹Π·Ρ‹Π²Π°ΠΉΡ‚Π΅ AddRef послС присваивания. Когда Π±Ρ‹ Π’Ρ‹ Π½ΠΈ присваивали ΠΎΠ΄ΠΈΠ½ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΈΠ½Ρ‚СрфСйс Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ, Π²Ρ‹Π·Ρ‹Π²Π°ΠΉΡ‚Π΅ AddRef. Π˜Π½Ρ‹ΠΌΠΈ словами: слСдуСт ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ΡŒ счСтчик ссылок ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° создаСтся новая ссылка Π½Π° Π΄Π°Π½Π½Ρ‹ΠΉ интСрфСйс.

ΠŸΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΉ Π½ΠΈΠΆΠ΅ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠ΄Π° создаСт ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΈΠ½Ρ‚СрфСйс IX. ΠœΡ‹ Π½Π΅ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ AddRef, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π·Π° Π½Π°Ρ это Π΄Π΅Π»Π°ΡŽΡ‚ CreateInstance ΠΈ QueryInterface. Однако ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Release ΠΊΠ°ΠΊ для интСрфСйса IUnknown, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½Π½ΠΎΠ³ΠΎ CreateInstance, Ρ‚Π°ΠΊ ΠΈ Π΄Π»Ρ интСрфСйса IX, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½Π½ΠΎΠ³ΠΎ QueryInterface.

// Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚

IUnknown* pIUnknown = CreateInstance ();

// ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ интСрфСйс IX

IX* pIX = NULL;

HRESULT hr = pIUnknown->QueryInterface (IID_IX, (void**)&pIX);

if (SUCCEEDED (hr))

{

pIX->Fx (); // Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ интСрфСйс IX

pIX->Release (); // Π—Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ с IX

}

pIUnknown->Release (); // Π—Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ с Iunknown

Π’ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌ Π²Ρ‹ΡˆΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΌΡ‹ Ρ„актичСски Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΠ»ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с IUnknown сразу ΠΆΠ΅ послС Π²Ρ‹Π·ΠΎΠ²Π°

QueryInterface, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ Ρ€Π°Π½ΡŒΡˆΠ΅.

// Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚

IUnknown* pIUnknown = CreateInstance ();

// ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ интСрфСйс IX

IX* pIX = NULL;

HRESULT hr = pIUnknown->QueryInterface (IID_IX, (void**)&pIX);

// Π—Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ с IUnknown

pIUnknown->Release ();

// Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ IX, Ссли ΠΎΠ½ Π±Ρ‹Π» ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ

if (SUCCEEDED (hr))

{

pIX->Fx (); // Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ интСрфСйс IX

pIX->Release (); // Π—Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ с IX

}

Π›Π΅Π³ΠΊΠΎ Π·Π°Π±Ρ‹Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ всякий Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° Π’Ρ‹ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΈΠ½Ρ‚СрфСйс, Π½Π°Π΄ΠΎ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ΡŒ Π΅Π³ΠΎ счСтчик ссылок. Π’ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌ Π΄Π°Π»Π΅Π΅ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π΅ ΠΊΠΎΠ΄Π° дСлаСтся Π΅Ρ‰Π΅ ΠΎΠ΄Π½Π° ссылка Π½Π° ΠΈΠ½Ρ‚СрфСйс IX. Π’ ΠΎΠ±Ρ‰Π΅ΠΌ случаС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Ρ‚ΡŒ счСтчик ссылок всякий Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° создаСтся копия указатСля Π½Π° ΠΈΠ½Ρ‚СрфСйс, ΠΎ Ρ‡Π΅ΠΌ Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠ΅ Π²Ρ‹ΡˆΠ΅ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 3.

// Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚

IUnknown* pIUnknown = CreateInstance ();

IX* pIX = NULL;

HRESULT hr = pIUnknown->QueryInterface (IID_IX, (void**)&pIX);

pIUnknown->Release ();

if (SUCCEEDED (hr))

{

pIX->Fx (); // Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ интСрфСйс IX

IX* pIX2 = pIX; // Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ копию pIX

pIX2->AddRef (); // Π£Π²Π΅Π»ΠΈΡ‡ΠΈΡ‚ΡŒ счСтчик ссылок

pIX2->Fx (); // Π§Ρ‚ΠΎ-Ρ‚ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ pIX2

pIX2->Release (); // Π—Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ с pIX2

pIX->Release (); // Π—Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ с pIX

}

ΠšΠ»ΠΈΠ΅Π½Ρ‚ сообщаСт ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρƒ ΠΎ ΡΠ²ΠΎΠ΅ΠΌ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ интСрфСйс, ΠΊΠΎΠ³Π΄Π° вызываСтся

QueryInterface. QueryInterface Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ AddRef для Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌΠΎΠ³ΠΎ интСрфСйса. Когда ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°ΠΊΠ°Π½Ρ‡ΠΈΠ²Π°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ с ΠΈΠ½Ρ‚СрфСйсом, ΠΎΠ½ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ для этого интСрфСйса Release. ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ остаСтся Π² ΠΏΠ°ΠΌΡΡ‚ΠΈ, оТидая, ΠΏΠΎΠΊΠ° счСтчик ссылок Π½Π΅ ΡΡ‚Π°Π½Π΅Ρ‚ Ρ€Π°Π²Π΅Π½ 0. Когда счСтчик становится Π½ΡƒΠ»Π΅ΠΌ, ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ сам сСбя удаляСт.

ВСкст ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹:

#include «stdafx.h»

#include «iostream.h»

#include «objbase.h»

#include «conio.h»

void trace (const char* msg) { cout << msg << endl; }

// ΠŸΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ описания GUID

extern const IID IID_IX;

extern const IID IID_IY;

extern const IID IID_IZ;

// Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡΡ‹

interface IX: IUnknown

{

virtual void __stdcall Fx () = 0;

};

interface IY: IUnknown

{

virtual void __stdcall Fy () = 0;

};

interface IZ: IUnknown

{

virtual void __stdcall Fz () = 0;

};

// ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚

class CA: public IX, public IY

{

// РСализация IUnknown

virtual HRESULT __stdcall QueryInterface (const IID& iid, void** ppv);

virtual ULONG __stdcall AddRef ();

virtual ULONG __stdcall Release ();

// РСализация интСрфСйса IX

virtual void __stdcall Fx () { cout << «Fx» << endl; }

// РСализация интСрфСйса IY

virtual void __stdcall Fy () { cout << «Fy» << endl; }

public:

// ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€

CA (): m_cRef (0) {}

// ДСструктор

~CA () { trace («CA: Likvidirovat' seby»); }

private:

long m_cRef;

};

HRESULT __stdcall CA: QueryInterface (const IID& iid, void** ppv)

{

if (iid == IID_IUnknown)

{

trace («CA QI: Vozvratit' ykazateel na IUnknown»);

*ppv = static_cast (this);

}

else if (iid == IID_IX)

{

trace («CA QI: Vozvratit' ykazateel na IX»);

*ppv = static_cast (this);

}

else if (iid == IID_IY)

{

trace («CA QI: Vozvratit' ykazateel na IY»);

*ppv = static_cast (this);

}

else

{

trace («CA QI: Interface No!»);

*ppv = NULL;

return E_NOINTERFACE;

}

reinterpret_cast (*ppv)->AddRef ();

return S_OK;

}

ULONG __stdcall CA: AddRef ()

{

cout << «CA: AddRef = «<< m_cRef+1 << endl;

return InterlockedIncrement (&m_cRef);

}

ULONG __stdcall CA: Release ()

{

cout << «CA: Release = «<< m_cRef-1 << endl;

if (InterlockedDecrement (&m_cRef) == 0)

{

delete this;

return 0;

}

return m_cRef;

}

// Ѐункция создания

IUnknown* CreateInstance ()

{

IUnknown* pI = static_cast (new CA);

pI->AddRef ();

return pI;

}

// IID

// {32bb8320-b41b-11cf-a6bb-0080c7b2d682}

static const IID IID_IX =

{0×32bb8320, 0xb41b, 0×11cf,

{0xa6, 0xbb, 0×0, 0×80, 0xc7, 0xb2, 0xd6, 0×82}};

// {32bb8321-b41b-11cf-a6bb-0080c7b2d682}

static const IID IID_IY =

{0×32bb8321, 0xb41b, 0×11cf,

{0xa6, 0xbb, 0×0, 0×80, 0xc7, 0xb2, 0xd6, 0×82}};

// {32bb8322-b41b-11cf-a6bb-0080c7b2d682}

static const IID IID_IZ =

{0×32bb8322, 0xb41b, 0×11cf,

{0xa6, 0xbb, 0×0, 0×80, 0xc7, 0xb2, 0xd6, 0×82}};

// ΠšΠ»ΠΈΠ΅Π½Ρ‚

int main ()

{

HRESULT hr;

trace («Client: Polychit' ykazatel IUnknown»);

IUnknown* pIUnknown = CreateInstance ();

trace («Client: Polychit' Interface IX»);

IX* pIX = NULL;

hr = pIUnknown->QueryInterface (IID_IX, (void**)&pIX);

if (SUCCEEDED (hr))

{

trace («Client: IX polychen»);

pIX->Fx (); // Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ интСрфСйс IX

pIX->Release ();

}

trace («Client: Polychit' Interface IY»);

IY* pIY = NULL;

hr = pIUnknown->QueryInterface (IID_IY, (void**)&pIY);

if (SUCCEEDED (hr))

{

trace («Client: IY polychen»);

pIY->Fy (); // Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ интСрфСйс IY

pIY->Release ();

}

trace («Client: Zaprosit' nepodderjivaemue Interface»);

IZ* pIZ = NULL;

hr = pIUnknown->QueryInterface (IID_IZ, (void**)&pIZ);

if (SUCCEEDED (hr))

{

trace («Client: Interface IZ polychen»);

pIZ->Fz ();

pIZ->Release ();

}

else

{

trace («Client: No! Interface IZ»);

}

trace («Client: Osvobodit' Interface IUnknown»);

pIUnknown->Release ();

getch ();

return 0;

}

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹:

Π’Ρ‹Π²ΠΎΠ΄:

Π’ ΡΡ‚ΠΎΠΌ Π·Π°Π΄Π°Π½ΠΈΠΈ ΠΌΡ‹ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ подсчСт ссылок. Для этого ΠΊ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρƒ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π΄Π²ΡƒΡ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² IUnknown — AddRef ΠΈ Release, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Win32 InterlockedIncrement ΠΈ InterlockedDecrement. Π€ΡƒΠ½ΠΊΡ†ΠΈΡŽ AddRef Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ CreateInstance ΠΈ QueryInterface для ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π° ΠΈΠ½Ρ‚СрфСйсы. Π’Ρ‹Π·ΠΎΠ²Ρ‹ Release Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ Π² ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡ΠΈΡ‚ΡŒ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΠ΅ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ интСрфСйсами. Π›ΠΈΠΊΠ²ΠΈΠ΄ΠΈΡ€ΠΎΠ²Π°Π»ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ дСструктора.

ΠŸΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ вСсь тСкст
Π—Π°ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Ρ„ΠΎΡ€ΠΌΡƒ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Ρ€Π°Π±ΠΎΡ‚ΠΎΠΉ