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

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

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

ΠŸΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ Π½Π° Visual Basic ΠΈ Java, Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ C++, программисты Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ видят QueryInterface, AddRef ΠΈΠ»ΠΈ Release. Для этих Π΄Π²ΡƒΡ… языков Π΄Π΅Ρ‚Π°Π»ΠΈ IUnknown Π½Π°Π΄Π΅ΠΆΠ½ΠΎ скрыты Π·Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰Π΅ΠΉ эти языки Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΉ машиной. На Java QueryInterface просто отобраТаСтся Π² ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ°:


public void TryToSnoreAndIgnore(Object obj)

{

IPug pug;

try

{

pug = (IPug)obj;

// VM calls QueryInterface

// VM Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ QueryInterface

pug.Snore();

}

catch (Throwable ex)

{

// ignore method or QI failures

// ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΠ΅ΠΌ сбой ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΈΠ»ΠΈ QI

}

ICat cat;

try

{

cat = (ICat)obj;

// VM calls QueryInterface

// VM Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ QueryInterface

cat.IgnoreMaster();

}

catch (Throwable ex)

{

// ignore method or QI failures

// игнорируСтся сбой ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΈΠ»ΠΈ QI

}

}


Visual Basic Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² привСдСния Ρ‚ΠΈΠΏΠΎΠ². ВмСсто этого, ΠΊΠΎΠ³Π΄Π° ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ интСрфСйса присваиваСтся ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ нСподходящСго Ρ‚ΠΈΠΏΠ°, Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Π°Ρ машина (VM) Visual Basic ΠΌΠΎΠ»Ρ‡Π° Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ QueryInterface ΠΎΡ‚ ΠΈΠΌΠ΅Π½ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°:


Sub TryToSnoreAndIgnore(obj as Object)

On Error Resume Next

' ignore errors

' ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΠ΅ΠΌ ошибки

Dim pug as IPug

Set pug = obj

' VM calls QueryInterface

' VM Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ QueryInterface

If Not (pug is Nothing)

Then pug.Snore

End

if Dim cat as ICat

Set cat = obj

' VM calls QueryInterface

' VM Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ QueryInterface

If Not (cat is Nothing)

Then cat.IgnoreMaster

End if End Sub


ОбС Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΌΠ°ΡˆΠΈΠ½Ρ‹, ΠΊΠ°ΠΊ Java, Ρ‚Π°ΠΊ ΠΈ Visual Basic, выбросят ΠΏΡ€ΠΈ сбоС QueryInterface ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ. Π’ ΠΎΠ±Π΅ΠΈΡ… срСдах Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Π°Ρ машина автоматичСски ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ ΡΠ·Ρ‹ΠΊΠΎΠ²ΡƒΡŽ ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΡŽ ТивучСсти ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π² явныС Π²Ρ‹Π·ΠΎΠ²Ρ‹ AddRef ΠΈ Release , избавляя ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΈ ΠΎΡ‚ этой подробности.

Одна ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊΠ°, ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ способная ΡƒΠΏΡ€ΠΎΡΡ‚ΠΈΡ‚ΡŒ использованиС Π² БОМ интСрфСйсных ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ ΠΈΠ· C++, состоит Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΊΡ€Ρ‹Ρ‚ΡŒ ΠΈΡ… Π² классС ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ. Π­Ρ‚ΠΎ устраняСт Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ Π½Π΅ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹Ρ… (raw ) Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² IUnknown. Π’ ΠΈΠ΄Π΅Π°Π»Π΅ ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ БОМ Π±ΡƒΠ΄Π΅Ρ‚:


ΠšΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ² Add/Release Π²ΠΎ врСмя присваивания.

АвтоматичСски ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°Ρ‚ΡŒ интСрфСйс Π² дСструкторС, Ρ‡Ρ‚ΠΎ сниТаСт Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΡƒΡ‚Π΅Ρ‡ΠΊΠΈ рСсурса ΠΈ ΠΏΠΎΠ²Ρ‹ΡˆΠ°Π΅Ρ‚ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ (Π½Π°Π΄Π΅ΠΆΠ½ΠΎΡΡ‚ΡŒ) ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ.

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ систСму Ρ‚ΠΈΠΏΠΎΠ² C++ для упрощСния Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² QueryInterface.

ΠŸΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ (Π½Π΅Π·Π°ΠΌΠ΅Ρ‚Π½ΠΎ для ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΈΠ»ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹) Π·Π°ΠΌΠ΅Ρ‰Π°Π΅Ρ‚ Π½Π΅ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹Π΅ интСрфСйсныС ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π² ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌ ΠΊΠΎΠ΄Π΅ Π±Π΅Π· ΠΊΠΎΠΌΠΏΡ€ΠΎΠΌΠ΅Ρ‚Π°Ρ†ΠΈΠΈ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.


ПослСдний ΠΏΡƒΠ½ΠΊΡ‚ прСдставляСт собой Ρ‡Ρ€Π΅Π·Π²Ρ‹Ρ‡Π°ΠΉΠ½ΠΎ ΡΠ΅Ρ€ΡŒΠ΅Π·Π½ΡƒΡŽ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ. Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚ Π·Π°Π±ΠΈΡ‚ ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΌΠΈ БОМ-указатСлями, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΡ€ΠΎΠ΄Π΅Π»Ρ‹Π²Π°ΡŽΡ‚ ΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½ΡƒΡŽ Π·Π°ΠΌΠ΅Π½Ρƒ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Ρ… ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ, Π½ΠΎ ΠΏΡ€ΠΈ этом вводят ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΆΠ΅ скрытых ошибок, сколько ΠΏΡ€Π΅Ρ‚Π΅Π½Π΄ΡƒΡŽΡ‚ ΡƒΡΡ‚Ρ€Π°Π½ΠΈΡ‚ΡŒ. Visual C++ 5.0, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, фактичСски дСйствуСт с трСмя Ρ‚Π°ΠΊΠΈΠΌΠΈ указатСлями (ΠΎΠ΄ΠΈΠ½ Π½Π° MSC, Π΄Ρ€ΡƒΠ³ΠΎΠΉ Π½Π° ATL, Π° Ρ‚Ρ€Π΅Ρ‚ΠΈΠΉ для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ Direct-to-COM), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΡ‡Π΅Π½ΡŒ просто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ, Ρ‚Π°ΠΊ ΠΈ Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ. Π’ ΡΠ΅Π½Ρ‚ΡΠ±Ρ€ΡŒΡΠΊΠΎΠΌ 1995 Π³ΠΎΠ΄Π° ΠΈ Π² Ρ„Π΅Π²Ρ€Π°Π»ΡŒΡΠΊΠΎΠΌ 1996 Π³ΠΎΠ΄Π° выпусках "C++ Report " ΠΎΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½Ρ‹ Π΄Π²Π΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ, Π³Π΄Π΅ Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ… ΠΏΠΎΠΊΠ°Π·Π°Π½Ρ‹ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ ΠΏΠΎΠ΄Π²ΠΎΠ΄Π½Ρ‹Π΅ ΠΊΠ°ΠΌΠ½ΠΈ ΠΏΡ€ΠΈ использовании ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ[1]. Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ приводится Π² Π΄Π°Π½Π½ΠΎΠΉ ΠΊΠ½ΠΈΠ³Π΅, содСрТит ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΉ БОМ-ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ, созданный Π² процСссС написания этих Π΄Π²ΡƒΡ… статСй. Π’ Π½Π΅ΠΌ дСлаСтся ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° ΡƒΡ‡Π΅ΡΡ‚ΡŒ ΠΎΠ±Ρ‰ΠΈΠ΅ ошибки, ΡΠ»ΡƒΡ‡Π°ΡŽΡ‰ΠΈΠ΅ΡΡ ΠΊΠ°ΠΊ Π² простых, Ρ‚Π°ΠΊ ΠΈ Π² ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… указатСлях БОМ. Класс ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ, SmartInterface , ΠΈΠΌΠ΅Π΅Ρ‚ Π΄Π²Π° ΡˆΠ°Π±Π»ΠΎΠ½Π½Ρ‹Ρ… (template) ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°: Ρ‚ΠΈΠΏ интСрфСйса Π² C++ ΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ IID . ВсС обращСния ΠΊ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌ IUnknown скрыты ΠΏΡƒΡ‚Π΅ΠΌ ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ²:


#include Β«smartif.hΒ»

void TryToSnoreAndIgnore(/* [in] */ IUnknown *pUnk)

{

// copy constructor calls QueryInterface

// конструктор копирования Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ QueryInterface

SmartInterface<IPug, &IIDIPug> pPug = pUnk;

if (pPug)

// typecast operator returns null-ness

// ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ привСдСния Ρ‚ΠΈΠΏΠ° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½ΡƒΠ»ΡŒ pPug->Snore();

// operator-> returns safe raw ptr

// ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ -> Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ прямой ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ

// copy constructor calls QueryInterface

// конструктор копирования Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ QueryInterface

SmartInterface<ICat, &IIDICat> pCat = pUnk;

if (pCat)

// typecast operator returns null-ness

// ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ привСдСния Ρ‚ΠΈΠΏΠ° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½ΡƒΠ»ΡŒ pCat->IgnoreMaster();

// operator-> returns safe raw ptr

// ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ -> Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ прямой ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ

// destructors release held pointers on leaving scope

// дСструкторы ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°ΡŽΡ‚ ΡƒΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ ΠΏΡ€ΠΈ

// Π²Ρ‹Ρ…ΠΎΠ΄Π΅ ΠΈΠ· области дСйствия

}


Π˜Π½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ выглядят ΠΎΡ‡Π΅Π½ΡŒ ΠΏΡ€ΠΈΠ²Π»Π΅ΠΊΠ°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ Π½Π° ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ взгляд, Π½ΠΎ ΠΌΠΎΠ³ΡƒΡ‚ ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ ΠΎΡ‡Π΅Π½ΡŒ опасными, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΏΠΎΠ³Ρ€ΡƒΠΆΠ°ΡŽΡ‚ программиста Π² Π΄Ρ€Π΅ΠΌΠΎΡ‚Π½ΠΎΠ΅ состояниС; Π±ΡƒΠ΄Ρ‚ΠΎ Π±Ρ‹ Π½ΠΈΡ‡Π΅Π³ΠΎ ΡΡ‚Ρ€Π°ΡˆΠ½ΠΎΠ³ΠΎ, относящСгося ΠΊ БОМ, ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΡ‚ΠΈ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚. Π˜Π½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ€Π΅ΡˆΠ°ΡŽΡ‚ Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, особСнно связанныС с ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡΠΌΠΈ; ΠΎΠ΄Π½Π°ΠΊΠΎ ΠΏΡ€ΠΈ нСостороТном ΡƒΠΏΠΎΡ‚Ρ€Π΅Π±Π»Π΅Π½ΠΈΠΈ ΠΎΠ½ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ внСсти ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΆΠ΅ Π΄Π΅Ρ„Π΅ΠΊΡ‚ΠΎΠ², сколько ΠΎΠ½ΠΈ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚. НапримСр, ΠΌΠ½ΠΎΠ³ΠΈΠ΅ ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ любой ΠΌΠ΅Ρ‚ΠΎΠ΄ интСрфСйса Ρ‡Π΅Ρ€Π΅Π· ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ указатСля –>. К соТалСнию, это позволяСт ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Release с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ этого ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π°-стрСлки Π±Π΅Π· сообщСния Π±Π°Π·ΠΎΠ²ΠΎΠΌΡƒ ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΌΡƒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŽ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π΅Π³ΠΎ автоматичСский Π²Ρ‹Π·ΠΎΠ² Release Π² Π΅Π³ΠΎ дСструкторС Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ являСтся излишним ΠΈ нСдопустимым.


ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ QueryInterface

ЀактичСски рСализация QueryInterface, показанная Ρ€Π°Π½Π΅Π΅ Π² этой Π³Π»Π°Π²Π΅, ΠΎΡ‡Π΅Π½ΡŒ проста ΠΈ Π»Π΅Π³ΠΊΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒΡΡ Π»ΡŽΠ±Ρ‹ΠΌ программистом, ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΠΌ Ρ…ΠΎΡ‚ΡŒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ прСдставлСниС ΠΎ БОМ ΠΈ C++. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, ΠΌΠ½ΠΎΠ³ΠΈΠ΅ срСды ΠΈ каркасы ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ, ΡƒΠΏΡ€Π°Π²Π»ΡΠ΅ΠΌΡƒΡŽ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ. Π­Ρ‚ΠΎ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ Π΄ΠΎΡΡ‚ΠΈΡ‡ΡŒ большСй Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΠΎΡΡ‚ΠΈ ΠΈ эффСктивности благодаря ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΡŽ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° ΠΊΠΎΠ΄Π°. Π’Π°ΠΊΠΈΠ΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°ΡŽΡ‚, Ρ‡Ρ‚ΠΎ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ совмСстимый с БОМ класс прСдусматриваСт Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ, которая ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅Ρ‚ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΉ IID Π½Π° ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ аспСкт ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ фиксированныС смСщСния ΠΈΠ»ΠΈ ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ способы. Π’ сущности, рСализация QueryInterface , привСдСнная Ρ€Π°Π½Π΅Π΅ Π² этой Π³Π»Π°Π²Π΅, строит Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ, ΠΎΡΠ½ΠΎΠ²Π°Π½Π½ΡƒΡŽ Π½Π° скомпилированном машинном ΠΊΠΎΠ΄Π΅ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΈΠ· ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² if, Π° фиксированныС смСщСния Π²Ρ‹Ρ‡ΠΈΡΠ»ΡΡŽΡ‚ΡΡ с использованиСм ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° staticcast (staticcast просто добавляСт смСщСниС Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π°ΠΉΡ‚ΠΈ совмСстимый с Ρ‚ΠΈΠΏΠΎΠΌ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ vptr).

Π§Ρ‚ΠΎΠ±Ρ‹ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ управляСмый Ρ‚Π°Π±Π»ΠΈΡ†Π΅ΠΉ QueryInterface, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ сначала ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ эта Ρ‚Π°Π±Π»ΠΈΡ†Π° Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ. Как ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ элСмСнт Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° IID ΠΈ Π½Π΅ΠΊΠΎΠ΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ состояниС, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π½Π°ΠΉΡ‚ΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ vptr ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° для Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½Π½ΠΎΠ³ΠΎ интСрфСйса. Π₯Ρ€Π°Π½Π΅Π½ΠΈΠ΅ указатСля Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ элСмСнтС Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ придаст этому способу ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½ΡƒΡŽ Π³ΠΈΠ±ΠΊΠΎΡΡ‚ΡŒ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ это даст Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ Π½ΠΎΠ²Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊΠΈ поиска интСрфСйсов ΠΊ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΌΡƒ Π²Ρ‹Ρ‡ΠΈΡΠ»Π΅Π½ΠΈΡŽ смСщСния, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для привСдСния ΠΊ Π±Π°Π·ΠΎΠ²ΠΎΠΌΡƒ классу. Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ ΠΊ Π΄Π°Π½Π½ΠΎΠΉ ΠΊΠ½ΠΈΠ³Π΅ содСрТит Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» inttable.h , ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ опрСдСляСт элСмСнты Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ интСрфСйсов ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:


// inttable.h (book-specific header file)

// inttable.h (Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ», спСцифичСский для этой ΠΊΠ½ΠΈΠ³ΠΈ)

// typedef for extensibility function

// typedef для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΠΎΡΡ‚ΠΈ

typedef HRESULT (*INTERFACEFINDER) (void *pThis, DWORD dwData, REFIID riid, void **ppv);

// pseudo-function to indicate entry is just offset

// псСвдофункция для ΠΈΠ½Π΄ΠΈΠΊΠ°Ρ†ΠΈΠΈ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ запись просто

// являСтся смСщСниСм

#define ENTRYISOFFSET INTERFACEFINDER(-1)

// basic table layout // прСдставлСниС Π±Π°Π·ΠΎΠ²ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹

typedef struct INTERFACEENTRY

{

const IID * pIID;

// the IID to match

// ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ IID

INTERFACEFINDER pfnFinder;

// функция finder DWORD dwData;

// offset/aux data

// Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎ offset/aux

} INTERFACEENTRY;


Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» Ρ‚Π°ΠΊΠΆΠ΅ содСрТит ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ макросы для создания интСрфСйсных Ρ‚Π°Π±Π»ΠΈΡ† Π²Π½ΡƒΡ‚Ρ€ΠΈ опрСдСлСния класса:


// Inttable.h (book-specific header file)

// Inttable.h (Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ», спСцифичСский для Π΄Π°Π½Π½ΠΎΠΉ ΠΊΠ½ΠΈΠ³ΠΈ)