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

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

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

ИмСя Ρ‚Π°ΠΊΡƒΡŽ ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΡŽ Ρ‚ΠΈΠΏΠΎΠ², ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΌΠΎΠΆΠ΅Ρ‚ динамичСски Π·Π°ΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΎ Π΄Π°Π½Π½ΠΎΠΌ интСрфСйсС с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ Π½Π΅ зависящСй ΠΎΡ‚ транслятора конструкции:


bool SaveString(IFastString *pfs, const char *pszFN) { boot bResult = false; IPersistentObject *ppo = (IPersistentObject) pfs->Dynamic_Cast(Β«IPers1stentObjectΒ»); if (ppo) bResult = ppo->Save(pszFN); return bResult; }


Π’ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ клиСнтского использования ΠΏΡ€ΠΈΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚ трСбуСмая сСмантика ΠΈ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ для опрСдСлСния Ρ‚ΠΈΠΏΠ°, Π½ΠΎ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ класс Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ это Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ΅ Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ самолично:


class FastString : public IFastString, public IPersistentObject

{

int m_cсh;

// count of characters

// счСтчик символов

char *m_psz;

public:

FastString(const char *psz);

~FastString(void);

// IExtensibleObject methods

// ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ IExtensibleObject

void *Dynamic_Cast(const char *pszType);

void Delete(void);

// deletes this instance

// удаляСт этот экзСмпляр

// IFastString methods

// ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ IFastString

int Length(void) const;

// returns # of characters

// Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ число символов

int Find(const char *psz) const;

// returns offset

// Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ смСщСниС

// IPersistentObject methods

// ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ IPersistentObject

bool Load(const char *pszFileName);

bool Save(const char *pszFileName);

};


Π Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Dynamic_Cast Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΠΌΠΈΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ дСйствия RTTI ΠΏΡƒΡ‚Π΅ΠΌ управлСния ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΠ΅ΠΉ Ρ‚ΠΈΠΏΠΎΠ² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. Рисунок 1.8 ΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΡŽ Ρ‚ΠΈΠΏΠΎΠ² для Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚ΠΎ ΠΏΠΎΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ класса FastString. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ класс Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ пороТдаСтся ΠΈΠ· ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ интСрфСйса, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠ½ выставляСт, рСализация Dynamic_Cast Π² FastString ΠΌΠΎΠΆΠ΅Ρ‚ просто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ явныС статичСскиС привСдСния Ρ‚ΠΈΠΏΠ° (explicit static casts), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ дСйствия указатСля this, основанного Π½Π° ΠΏΠΎΠ΄Ρ‚ΠΈΠΏΠ΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ:


void *FastString::Dynam1c_Cast(const char *pszType)

{

if (strcmp(pszType, Β«IFastStringΒ») == 0) return static_cast<IFastString*>(this);

else if (strcmp(pszType, Β«IPersistentObjectΒ») == 0) return static_cast<IPersistentObject*>(this);

else if (strcmp(pszType, Β«IExtensibleObjectΒ») == 0) return static_cast<IFastString*>(this);

else return 0;

// request for unsupported interface

// запрос Π½Π° Π½Π΅ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΉ интСрфСйс

}




Π’Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ пороТдаСтся ΠΎΡ‚ Ρ‚ΠΈΠΏΠ°, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ³ΠΎ Π² этом ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠΈ, оттранслированныС вСрсии ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² прСобразования просто Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ смСщСниС ΠΊ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŽ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° this, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π°ΠΉΡ‚ΠΈ Π½Π°Ρ‡Π°Π»ΠΎ прСдставлСния Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса.

ΠžΡ‚ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ послС запроса Π½Π° ΠΎΠ±Ρ‰ΠΈΠΉ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ интСрфСйс IExtensibleObject рСализация статичСски прСобразуСтся Π² IFastString. Π­Ρ‚ΠΎ происходит ΠΏΠΎΡ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ интуитивная вСрсия (intuitive version) ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π°

return static_cast<IExtensibleObject*>(this);

Π½Π΅ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½Π°, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΈ IFastString, ΠΈ IPersistentObject ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½Ρ‹ ΠΎΡ‚ IExtensibleObject. Если Π±Ρ‹ IExtensibleObject Π±Ρ‹Π» Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΌ Π±Π°Π·ΠΎΠ²Ρ‹ΠΌ классом ΠΊΠ°ΠΊ для IFastString, Ρ‚Π°ΠΊ ΠΈ для IPersistentObject, Ρ‚ΠΎ Π΄Π°Π½Π½ΠΎΠ΅ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π΅ Π±Ρ‹Π»ΠΎ Π±Ρ‹ Π½Π΅ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½Ρ‹ΠΌ ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ Π±Ρ‹ оттранслировался. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… Π±Π°Π·ΠΎΠ²Ρ‹Ρ… классов добавляСт Π½Π° этапС выполнСния Π½Π΅Π½ΡƒΠΆΠ½ΡƒΡŽ ΡΠ»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈ ΠΊ Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ вносит Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ ΠΎΡ‚ транслятора. Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ Π±Π°Π·ΠΎΠ²Ρ‹Π΅ классы ΡΠ²Π»ΡΡŽΡ‚ΡΡ всСго лишь особСнностями языка C++, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ нСсколько спСцифичСских Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ.


Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ рСсурсами

Π•Ρ‰Π΅ ΠΎΠ΄Π½Π° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… интСрфСйсов ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° становится яснСС, Ссли ΠΈΡΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚ΡŒ схСму использования ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° DynamicCast. Рассмотрим ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΡΠΊΡƒΡŽ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ:


void f(void)

{

IFastString *pfs = 0;

IPersistentObject *ppo = 0;

pfs = CreateFastString(Β«Feed BOBΒ»);

if (pfs) {

ppo = (IPersistentObject *) pfs->DynamicCast(Β«IPersistentObjectΒ»);

if (!ppo) pfs->Delete();

else { ppo->Save(Β«C:\\autoexec.batΒ»);

ppo->Delete(); }

}

}


Π₯отя Π²Π½Π°Ρ‡Π°Π»Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π±Ρ‹Π» связан Ρ‡Π΅Ρ€Π΅Π· свой интСрфСйс IFastString , клиСнтский ΠΊΠΎΠ΄ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ Delete Ρ‡Π΅Ρ€Π΅Π· интСрфСйс IPersistentObject. Π‘ использованиСм свойства C++ ΠΎ мноТСствСнном наслСдовании это Π²ΠΏΠΎΠ»Π½Π΅ допустимо, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ всС Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ vtbl , ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½Π½Ρ‹Π΅ классом IExtensibleObject, ΡƒΠΊΠ°ΠΆΡƒΡ‚ Π½Π° Π΅Π΄ΠΈΠ½ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Delete . Π’Π΅ΠΏΠ΅Ρ€ΡŒ, ΠΎΠ΄Π½Π°ΠΊΠΎ, ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π΄ΠΎΠ»ΠΆΠ΅Π½ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊΠΈΠ΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ связаны с ΠΊΠ°ΠΊΠΈΠΌΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ, ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Delete Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚. Π’ случаС простого ΠΊΠΎΠ΄Π°, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠ³ΠΎ Π²Ρ‹ΡˆΠ΅, это Π½Π΅ слишком тяТСлоС брСмя. Для Π±ΠΎΠ»Π΅Π΅ слоТных клиСнтских ΠΊΠΎΠ΄ΠΎΠ² ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ этими связями становится Π΄Π΅Π»ΠΎΠΌ вСсьма слоТным ΠΈ Ρ‡Ρ€Π΅Π²Π°Ρ‚Ρ‹ΠΌ ошибками. Одним ΠΈΠ· способов упрощСния Π·Π°Π΄Π°Ρ‡ΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ являСтся Π²ΠΎΠ·Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ отвСтствСнности Π·Π° ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΆΠΈΠ·Π½Π΅Π½Π½Ρ‹ΠΌ Ρ†ΠΈΠΊΠ»ΠΎΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π½Π° Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ явно ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ вскрываСт Π΅Ρ‰Π΅ ΠΎΠ΄Π½Ρƒ Π΄Π΅Ρ‚Π°Π»ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ: Ρ‚ΠΎΡ‚ Ρ„Π°ΠΊΡ‚, Ρ‡Ρ‚ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ находится Π² динамичСски распрСдСляСмой памяти (Π² Β«ΠΊΡƒΡ‡Π΅Β», on the heap).

ΠŸΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠ΅Π΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ этой ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ – ввСсти Π² ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ счСтчик ссылок, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ увСличиваСтся, ΠΊΠΎΠ³Π΄Π° ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ интСрфСйса дублируСтся, ΠΈ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ΡΡ, ΠΊΠΎΠ³Π΄Π° ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ интСрфСйса уничтоТаСтся. Π­Ρ‚ΠΎ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ опрСдСлСния IExtensibleObject с


class IExtensibleObject

{

public:

virtual void *DynamicCast (const char* pszType) =0;

virtual void Delete(void) = 0;

};


Π½Π°


class IExtensibleObject

{

public:

virtual void *DynamicCast(const char* pszType) = 0;

virtual void DuplicatePointer(void) = 0;

virtual void DestroyPointer(void) = 0;

};


РазмСстив эти ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹, всС ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ IExtensibleObject Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΡ€ΠΈΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒΡΡ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… Π΄Π²ΡƒΡ… сообраТСний:

1) Когда ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ интСрфСйса дублируСтся, трСбуСтся Π²Ρ‹Π·ΠΎΠ² DuplicatePointer.

2) Когда ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ интСрфСйса Π±ΠΎΠ»Π΅Π΅ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ, слСдуСт Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ DestroyPointer.

Π­Ρ‚ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ‹ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅: Π½ΡƒΠΆΠ½ΠΎ просто Ρ„ΠΈΠΊΡΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ количСство Π΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ ΠΈ ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΠ³Π΄Π° Π½Π΅Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹Ρ… ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π΅ ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ:


class FastString : public IFastString,

public IPersistentObject

{

int mcPtrs;

// count of outstanding ptrs

// счСтчик Π½Π΅Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹Ρ… ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ

public:

// initialize pointer count to zero

// ΡΠ±Ρ€ΠΎΡΠΈΡ‚ΡŒ счСтчик указатСля Π² Π½ΡƒΠ»ΡŒ

FastString(const char *psz) : mcPtrs(0) { }

void DuplicatePointer(void)

{

// note duplication of pointer

// ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ Π΄ΡƒΠ±Π»ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ указатСля

++mcPtrs;

}

void DestroyPointer(void)

{

// destroy object when last pointer destroyed

// ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΠ³Π΄Π° ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ΅Π½ послСдний ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ

if (-mcPtrs == 0) delete this;

}

: : :

};


Π­Ρ‚ΠΎΡ‚ ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ стандартный ΠΊΠΎΠ΄ ΠΌΠΎΠ³ Π±Ρ‹ просто Π±Ρ‹Ρ‚ΡŒ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ Π² Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ класс ΠΈΠ»ΠΈ Π² макрос Π‘-прСпроцСссора, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΅Π³ΠΎ ΠΌΠΎΠ³Π»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ всС Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ.

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ эти ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹, всС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠ°Π½ΠΈΠΏΡƒΠ»ΠΈΡ€ΡƒΡŽΡ‚ ΠΈΠ»ΠΈ ΡƒΠΏΡ€Π°Π²Π»ΡΡŽΡ‚ указатСлями интСрфСйса, Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΡ€ΠΈΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒΡΡ Π΄Π²ΡƒΡ… простых ΠΏΡ€Π°Π²ΠΈΠ» DuplicatePointer/DestroyPointer. Для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ FastString это ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ Π΄Π²ΡƒΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ. Ѐункция CreateFastString Π±Π΅Ρ€Π΅Ρ‚ Π½Π°Ρ‡Π°Π»ΡŒΠ½Ρ‹ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹ΠΉ Π½ΠΎΠ²Ρ‹ΠΌ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ C++, ΠΈ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ Π΅Π³ΠΎ Π² стСк для Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ. Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ Π²Ρ‹Π·ΠΎΠ² DuplicatePointer:


IFastString* CreateFastString(const char *psz)

{

IFastString *pfsResult = new FastString(psz);

if (pfsResult) pfsResult->DuplicatePointer();

return pfsResult;

}


РСализация ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ ΠΈ Π² Π΄Ρ€ΡƒΠ³ΠΎΠΌ мСстС – Π² ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ Dynamic_Cast:


void *FastString::Dynamic_Cast(const char *pszType)

{

void *pvResult = 0;

if (strcmp(pszType, Β«IFastStringΒ») == 0) pvResult = static_cast<IFastString*>(this);

else if (strcmp(pszType, Β«IPersistentObjectΒ») == 0) pvResult = static_cast<IPersistentObject*>(this); 

else if (strcmp(pszType, Β«IExtensibleObjectΒ») == 0) pvResult = static_cast<IFastString*>(this);

else return 0;

// request for unsupported interface

// запрос Π½Π° Π½Π΅ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΉ интСрфСйс

// pvResult now contains a duplicated pointer, so

// we must call DuplicatePointer prior to returning

// Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ pvResult содСрТит скопированный ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ,

// поэтому Π½ΡƒΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΎΠΌ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ DuplicatePointer

((IExtensibleObject*)pvResult)->DuplicatePo1nter();

return pvResult;

}

Π‘ этими двумя ΡƒΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½ΡΡ‚Π²ΠΎΠ²Π°Π½ΠΈΡΠΌΠΈ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ становится Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π±ΠΎΠ»Π΅Π΅ ΠΎΠ΄Π½ΠΎΡ€ΠΎΠ΄Π½Ρ‹ΠΌ ΠΈ ΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½Ρ‹ΠΌ:


void f(void)

{

IFastString *pfs = 0;

IPersistentObject *ppo = 0;

pfs = CreateFastString(Β«Feed BOBΒ»);

if (pts) {

Ρ€Ρ€ΠΎ = (IPersistentObject *) pfs->DynamicCast(Β«IPersistentObjectΒ»);

if (ppo) { ppo->Save(Β«C:\\autoexec.batΒ»);

ppo->DestroyPointer(); }

pfs->DestroyPointer(); }

}


ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ трактуСтся ΠΊΠ°ΠΊ Π°Π²Ρ‚ΠΎΠ½ΠΎΠΌΠ½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ с Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΆΠΈΠ·Π½ΠΈ, ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ ΠΌΠΎΠΆΠ½ΠΎ Π½Π΅ ΠΈΠ½Ρ‚Π΅Ρ€Π΅ΡΠΎΠ²Π°Ρ‚ΡŒΡΡ Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊΠΎΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ соотвСтствуСт ΠΊΠ°ΠΊΠΎΠΌΡƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ. ВмСсто этого ΠΊΠ»ΠΈΠ΅Π½Ρ‚ просто придСрТиваСтся Π΄Π²ΡƒΡ… простых ΠΏΡ€Π°Π²ΠΈΠ» ΠΈ прСдоставляСт ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌ самим ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ своим Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ ΠΆΠΈΠ·Π½ΠΈ. ΠŸΡ€ΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ способ Π²Ρ‹Π·ΠΎΠ²Π° DuplicatePointer ΠΈ DestroyPointer ΠΌΠΎΠΆΠ½ΠΎ Π»Π΅Π³ΠΊΠΎ ΡΠΊΡ€Ρ‹Ρ‚ΡŒ Π·Π° ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΌ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ (smart pointer) C++.

ИспользованиС этой схСмы вычислСния ссылок позволяСт ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ вСсьма Π΅Π΄ΠΈΠ½ΠΎΠΎΠ±Ρ€Π°Π·Π½ΠΎ Π²Ρ‹ΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ мноТСствСнныС интСрфСйсы. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ выставлСния Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… интСрфСйсов ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ класса Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ позволяСт Ρ‚ΠΈΠΏΡƒ Π΄Π°Π½Π½Ρ‹Ρ… ΡƒΡ‡Π°ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π² Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… контСкстах. НапримСр, новая постоянная подсистСма ΠΌΠΎΠ³Π»Π° Π±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ собствСнный интСрфСйс для управлСния Π°Π²Ρ‚ΠΎΠ·Π°Π³Ρ€ΡƒΠ·ΠΊΠΎΠΉ ΠΈ Π°Π²Ρ‚ΠΎΠ·Π°ΠΏΠΈΡΡŒΡŽ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π½Π° Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ спСциализированный Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒ. Класс FastString ΠΌΠΎΠ³ Π±Ρ‹ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ этих возмоТностСй простым наслСдованиСм ΠΎΡ‚ постоянного интСрфСйса этой подсистСмы. Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ этой ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ Π½ΠΈΠΊΠ°ΠΊ Π½Π΅ повлияСт Π½Π° ΡƒΠΆΠ΅ установлСнныС Π±Π°Π·Ρ‹ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅, ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ ΠΏΡ€Π΅ΠΆΠ½ΠΈΠΉ постоянный интСрфСйс для записи ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ строки Π½Π° диск. ΠœΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ согласования интСрфСйсов Π½Π° этапС выполнСния ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ»ΡƒΠΆΠΈΡ‚ΡŒ ΠΊΡ€Π°Π΅ΡƒΠ³ΠΎΠ»ΡŒΠ½Ρ‹ΠΌ ΠΊΠ°ΠΌΠ½Π΅ΠΌ для построСния динамичСской систСмы ΠΈΠ· ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ со Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ.