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

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

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

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 Π΄ΠΎΠ»ΠΆΠ½Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ‚ΠΎΡ‚ элСмСнт Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΉ интСрфСйс: