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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Windows APIΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 11

Автор А. Π›Π΅Π³Π°Π»ΠΎΠ²

private:

 FolderWatcher _folderWatcher;

};

Π’Π΅ΠΏΠ΅Ρ€ΡŒ, ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ Π·Π½Π°Π΅ΠΌ, ΠΊΠ°ΠΊ ΠΈΠΌΠ΅Ρ‚ΡŒ Π΄Π΅Π»ΠΎ с ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ΠΌ, Π΄Π°Π²Π°ΠΉΡ‚Π΅ взглянСм Π½Π° ΠΈΡ… источники, Бобытия ΠΈΠ·ΠΌΠ΅Π½ΡΡŽΡ‰ΠΈΠ΅ Ρ„Π°ΠΉΠ»Ρ‹. ΠžΠ±ΡŠΠ΅ΠΊΡ‚ события создан Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмой Π² ΠΎΡ‚Π²Π΅Ρ‚ Π½Π° FindFirstChangeNotification. ДСскриптор этого события Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ ΠΈΠ· Π²Ρ‹Π·ΠΎΠ²Π°. ΠœΡ‹ Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅ΠΌ этот дСскриптор ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π΅Π³ΠΎ ΠΏΠΎΠ·ΠΆΠ΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ»ΠΈ ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²ΠΈΡ‚ΡŒ восстанавлСниС ΠΈΠ»ΠΈ ΠΎΡ‚ΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ ΠΎΡ‚ нашСго интСрСса ΠΊ дальнСйшим увСдомлСниям. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒ наблююдСниС рСкурсивно, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ, Π½Π°Π±Π»ΡŽΠ΄Π°Ρ‚ΡŒ Π΄Π°Π½Π½ΡƒΡŽ ΠΏΠ°ΠΏΠΊΡƒ ΠΈ всС Π΅Π΅ ΠΏΠΎΠ΄ΠΏΠ°ΠΏΠΊΠΈ ΠΈ ΠΏΠΎΠ΄ΠΏΠΎΠ΄ΠΏΠ°ΠΏΠΊΠΈ. ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Ρ‚Π°ΠΊΠΆΠ΅ Π²Ρ‹Ρ€Π°ΠΆΠ°Ρ‚ΡŒ интСрСс ΠΊ спСцифичСским измСнСниям, пСрСдавая поразрядноС Π˜Π›Π˜ для любой ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… Ρ„Π»Π°ΠΆΠΊΠΎΠ²:

β€’ FILE_NOTIFY_CHANGE_FILE_NAME (ΠΏΠ΅Ρ€Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠ΅, созданиС ΠΈΠ»ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π°)

β€’ FILE_NOTIFY_CHANGE_DIR_NAME (созданиС ΠΈΠ»ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π° (ΠΏΠ°ΠΏΠΊΠΈ))

β€’ FILE_NOTIFY_CHANGE_ATTRIBUTES

β€’ FILE_NOTIFY_CHANGE_SIZE

β€’ FILE_NOTIFY_CHANGE_LAST_WRITE (сохранСниС Ρ„Π°ΠΉΠ»Π°)

β€’ FILE_NOTIFY_CHANGE_SECURITY

Для удобства ΠΌΡ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ нСсколько подклассов ΠΎΡ‚ FileChangeEvent, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‚ ΠΊ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ΠΌ комбинациям этих Ρ„Π»Π°ΠΆΠΊΠΎΠ². Один ΠΈΠ· Π½ΠΈΡ… β€” FolderChangeEvent, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ использовали Π² нашСм FolderWatcher.

class FileChangeEvent {

public:

 FileChangeEvent(char const *folder, BOOL recursive, DWORD notifyFlags) {

  _handle = FindFirstChangeNotification(folder, recursive, notifyFlags);

  if (INVALID_HANDLE_VALUE == _handle) throw WinException("Cannot create change notification handle");

 }

 ~FileChangeEvent() {

  if (INVALID_HANDLE_VALUE != _handle) FindCloseChangeNotification(_handle);

 }

 operator HANDLE() const { return _handle; }

 BOOL ContinueNotification() {

  return FindNextChangeNotification(_handle);

 }

private:

 HANDLE _handle;

};


class FolderChangeEvent : public FileChangeEvent {

public:

 FolderChangeEvent(char const* folder) : FileChangeEvent(folder, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME) {}

};


class TreeChangeEvent : public FileChangeEvent {

public:

 TreeChangeEvent(char const * root) : FileChangeEvent (root, TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME) {}

};

Π”ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ просто ΠΎΠ±ΠΎΠ±Ρ‰ΠΈΡ‚ΡŒ этот ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΡƒΡŽ Ρ€Π°Π±ΠΎΡ‚Ρƒ Π² Π²Π°ΡˆΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°Ρ…. НС Π·Π°Π±ΡƒΠ΄ΡŒΡ‚Π΅ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ API, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π² этих ΠΎΠ±ΡƒΡ‡Π°ΡŽΡ‰ΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°Ρ…, Π² ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠΉ справкС, которая ΠΈΠ΄Π΅Ρ‚ с вашим компилятором.

Π”Π°Π»Π΅Π΅: ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ OLE ΠΈ использованиС COM Π±Π΅Π· MFC.

ΠžΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ° ΠΈΠ· классов для COM

ИспользованиС ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΈ Windows совмСстно с COM

ΠŸΠ΅Ρ€Π΅Π²ΠΎΠ΄ А. И. Π›Π΅Π³Π°Π»ΠΎΠ²Π°

Англоязычный ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π» находится Π½Π° сСрвСрС ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΈ Reliable Software

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ с использованиСм COM Π½Π°ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Ρ€ΡƒΠ΄Π½ΠΎ, Ρ‡Ρ‚ΠΎ Π’Ρ‹ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π΄Π°ΠΆΠ΅ ΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ это Π±Π΅Π· MFC. ΠŸΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΈΠ»ΠΈ Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ? ΠΠ±ΡΠΎΠ»ΡŽΡ‚Π½Π°Ρ Ρ‡ΡƒΡˆΡŒ! Π Π΅ΠΊΠ»Π°ΠΌΠΈΡ€ΡƒΠ΅ΠΌΡ‹Π΅ OLE ΠΈ Π΅Π³ΠΎ ΠΏΡ€Π΅Π΅ΠΌΠ½ΠΈΠΊ COM ΠΈΠΌΠ΅ΡŽΡ‚ ΡΠ»Π΅Π³Π°Π½Ρ‚Π½ΠΎΡΡ‚ΡŒ Π³ΠΈΠΏΠΏΠΎΠΏΠΎΡ‚Π°ΠΌΠ°, Π·Π°Π½ΠΈΠΌΠ°ΡŽΡ‰Π΅Π³ΠΎΡΡ Ρ„ΠΈΠ³ΡƒΡ€Π½Ρ‹ΠΌ ΠΊΠ°Ρ‚Π°Π½ΠΈΠ΅ΠΌ. Но Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ MFC Π½Π° Π²Π΅Ρ€ΡˆΠΈΠ½Π΅ COM ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ одСванию Π³ΠΈΠΏΠΏΠΎΠΏΠΎΡ‚Π°ΠΌΠ° Π² клоунский ΠΊΠΎΡΡ‚ΡŽΠΌ Π΅Ρ‰Π΅ Π±ΠΎΠ»ΡŒΡˆΠΈΡ… Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ².

Π—Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚Π΅ исходник ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°, TreeSizer (zip Π°Ρ€Ρ…ΠΈΠ² 12 ΠΊΠ±, Π»ΡŽΠ±Π΅Π·Π½ΠΎΡΡ‚ΡŒ Laszlo Radanyi), Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ вычисляСтся суммарный Ρ€Π°Π·ΠΌΠ΅Ρ€ всСх Ρ„Π°ΠΉΠ»ΠΎΠ² Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π΅ ΠΈ всСх Π΅Π³ΠΎ ΠΏΠΎΠ΄ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°Ρ…. Он, для просмотра ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΎΠ², ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΎΠΊΠ½ΠΎ просмотра ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΈ Windows.

Π˜Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ программисту, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ столкнСтся с ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΎΡΡ‚ΡŒΡŽ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ возмоТности ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΈ Windows, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ доступными Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Π΅Ρ€Π΅Π· интСрфСйсы COM? Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ …

Для Π½Π°Ρ‡Π°Π»Π°, всякий Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° Π’Ρ‹ ΠΏΠ»Π°Π½ΠΈΡ€ΡƒΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ COM, Π’Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΠΎΠΎΠ±Ρ‰ΠΈΡ‚ΡŒ систСмС, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½Π° ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π»Π° COM подсистСму. Π’ΠΎΡ‡Π½ΠΎ Ρ‚Π°ΠΊ ΠΆΠ΅ всякий Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ Π·Π°ΠΊΠ°Π½Ρ‡ΠΈΠ²Π°Π΅Ρ‚Π΅ Ρ€Π°Π±ΠΎΡ‚Ρƒ, Π’Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΠΎΠΎΠ±Ρ‰ΠΈΡ‚ΡŒ систСмС, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½Π° Π²Ρ‹Π³Ρ€ΡƒΠ·ΠΈΠ»Π° COM. Бамая простой способ это ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, конструктор ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ COM, Π° дСструктор Π²Ρ‹Π³Ρ€ΠΎΠΆΠ°Π΅Ρ‚ Π΅Π΅. Π‘Π°ΠΌΠΎΠ΅ Π»ΡƒΡ‡ΡˆΠ΅Π΅ мСсто для внСдрСния Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° β€” это ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Controller (см. Windows ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ Generic), ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹ΠΉ этому.

class Controller {

public:

 Controller(HWND hwnd, CREATESTRUCT * pCreate);

 ~Controller();

 // … private:

 UseCom _comUser; // i'm a com user

 Model _model;

 View _view;

 HINSTANCE _hInst;

};

Π­Ρ‚ΠΎΡ‚ способ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΡŽΡ‚, Ρ‡Ρ‚ΠΎ COM подсистСма Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΎΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π° ΠΏΡ€Π΅ΠΆΠ΄Π΅, Ρ‡Π΅ΠΌ ΠΊ Π½Π΅ΠΉ Π±ΡƒΠ΄ΡƒΡ‚ сдСланы Π»ΡŽΠ±Ρ‹Π΅ обращСния ΠΈ Ρ‡Ρ‚ΠΎ ΠΎΠ½Π° Π±ΡƒΠ΄Π΅Ρ‚ освобоТдСна послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° осущСствит свои Ρ€Π°Π·Ρ€ΡƒΡˆΠ΅Π½ΠΈΡ (Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ, послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ "Π’ΠΈΠ΄" ΠΈ "МодСль" Π±ΡƒΠ΄ΡƒΡ‚ Ρ€Π°Π·Ρ€ΡƒΡˆΠ΅Π½Ρ‹).

Класс UseCom ΠΎΡ‡Π΅Π½ΡŒ прост.

class UseCom {

public:

 UseCom() {

  HRESULT err = CoInitialize(0);

  if (err != S_OK) throw "Couldn't initialize COM";

 }

 ~UseCom() {

  CoUninitialize();

 }

};

Пока Π½Π΅ Π±Ρ‹Π»ΠΎ слишком Ρ‚Ρ€ΡƒΠ΄Π½ΠΎ, Π½Π΅ Ρ‚Π°ΠΊ Π»ΠΈ? Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ ΠΊΠΎΡΠ½ΡƒΠ»ΠΈΡΡŒ Π³Π»Π°Π²Π½ΠΎΠΉ мСрзости COM программирования β€” подсчСта ссылок. Π’Π°ΠΌ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ извСстно, Ρ‡Ρ‚ΠΎ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° Ρ‡Ρ‚ΠΎ Π’Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚Π΅ интСрфСйс, Π΅Π³ΠΎ счСтчик ссылок увСличиваСтся. И Π’Π°ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ явно ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Ρ‚ΡŒ Π΅Π³ΠΎ. И это становится Π±ΠΎΠ»Π΅Π΅ Ρ‡Π΅ΠΌ уТастным Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° Π’Ρ‹ Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚Π΅ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Ρ‚ΡŒ интСрфСйсы, ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ…, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΈ Ρ‚.Π΄. Но Π»ΠΎΠ²ΠΈΡ‚Π΅ ΠΌΠΎΠΌΠ΅Π½Ρ‚: ΠΌΡ‹ Π·Π½Π°Π΅ΠΌ, ΠΊΠ°ΠΊ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒΡΡ с Ρ‚Π°ΠΊΠΈΠΌΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°ΠΌΠΈ! Π­Ρ‚ΠΎ называСтся ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ рСсурсами. ΠœΡ‹ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΊΠ°ΡΠ°Ρ‚ΡŒΡΡ интСрфСйсов COM Π±Π΅Π· инкапсуляции ΠΈΡ… Π² ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… указатСлях Π½Π° интСрфСйсы. НиТС ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ, ΠΊΠ°ΠΊ это Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚.

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅. Π’ настоящий ΠΌΠΎΠΌΠ΅Π½Ρ‚ данная Ρ‚Π΅ΠΌΠ° достаточно ΡˆΠΈΡ€ΠΎΠΊΠΎ рассмотрСна Π² Π»ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΡƒΡ€Π΅, ΠΏΠ΅Ρ€Π΅Π²Π΅Π΄Π΅Π½Π½ΠΎΠΉ Π½Π° русский язык. Π’ частности, ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ ΠΊΠ½ΠΈΠ³ΠΈ:

Π”ΠΆΠ΅Ρ„Ρ„ Π­Π»Π΄ΠΆΠ΅Ρ€. "C++: Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста";

Π‘ΠΊΠΎΡ‚Ρ‚ ΠœΠ΅ΠΉΠ΅Ρ€Ρ. "Π­Ρ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° Π‘++".

А.Π›.

template <class T>

class SIfacePtr {

public:

 ~SIfacePtr() {

  Free ();

 }

 T * operator->() { return _p; }

 T const* operator->() const { return _p; }

 operator T const * () const { return _p; }

 T const& GetAccess () const { return *_p; }

 protected: SIfacePtr () : _p (0) {}

 void Free () {

  if (_p != 0) _p->Release();

 _p = 0;

 }

 T * _p;

private:

 SIfacePtr(SIfacePtr const& p) {}

 void operator=(SIfacePtr const& p) {}

};

НС Π²ΠΎΠ»Π½ΡƒΠΉΡ‚Π΅, Ρ‡Ρ‚ΠΎ этот класс выглядит Π½Π΅ΠΏΡ€ΠΈΠ³ΠΎΠ΄Π½Ρ‹ΠΌ (ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΈΠΌΠ΅Π΅Ρ‚ Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Π½Ρ‹ΠΉ конструктор). ΠœΡ‹ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ нСпосрСдствСнно. ΠœΡ‹ наслСдуСм ΠΎΡ‚ Π½Π΅Π³ΠΎ. ΠœΠ΅ΠΆΠ΄Ρƒ ΠΏΡ€ΠΎΡ‡ΠΈΠΌ, это ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠ΅ΠΌ: создайтС класс с Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Π½Ρ‹ΠΌ пустым конструктором, ΠΈ осущСствитС наслСдованиС ΠΎΡ‚ Π½Π΅Π³ΠΎ. ВсС Π½Π°ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ классы Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°Ρ‚ΡŒ ΠΈΡ… Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΡŽΡŽ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ своими ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌΠΈ конструкторами. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΠΌΠ΅Ρ‚ΡŒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ классы, Π½Π°ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΎΡ‚ SIfacePtr, ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΡ‚Π»ΠΈΡ‡Π°Ρ‚ΡŒΡΡ ΠΏΠΎ способу получСния, ΠΏΠΎ ΠΈΡ… конструкторам, рассматриваСмым интСрфСйсам.

Π—Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ Ρ„ΠΈΠΊΡ‚ΠΈΠ²Π½Ρ‹ΠΉ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ конструктор ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ "=" Π½Π΅ всСгда Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹, Π½ΠΎ ΠΎΠ½ΠΈ сохранят Π’Π°ΠΌ врСмя, ΠΏΠΎΡ‚Ρ€Π°Ρ‡Π΅Π½Π½ΠΎΠ΅ Π½Π° ΠΎΡ‚Π»Π°Π΄ΠΊΡƒ, Ссли ΠΏΠΎ ошибкС Π²Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΄ΠΈΡ‚Π΅ ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΉ интСрфСйс ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ вмСсто ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΏΠΎ ссылкС. Π­Ρ‚ΠΎ большС Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ интСрфСйс, Π΄Π²Π°ΠΆΠ΄Ρ‹ ΠΈ это Π±ΡƒΠ΄Π΅Ρ‚ ΠΊΡ€ΡƒΡ‚ΠΎ ΠΎΡ‚Ρ€Π°ΠΆΠ°Ρ‚ΡŒΡΡ Π½Π° подсчСтС ссылок COM. Π’Π΅Ρ€ΡŒΡ‚Π΅ ΠΌΠ½Π΅, Ρƒ мСня это ΡΠ»ΡƒΡ‡Π°Π»ΠΎΡΡŒ. Как это часто Π±Ρ‹Π²Π°Π΅Ρ‚, компилятор откаТСтся ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΠΌΠ΅Π΅Ρ‚ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡƒΡŽ копию конструктора. Он Ρ‚Π°ΠΊΠΆΠ΅ выдаст ΠΎΡˆΠΈΠ±ΠΊΡƒ, ΠΊΠΎΠ³Π΄Π° Π’Ρ‹ ΠΏΡ€ΠΎΠ±ΡƒΠ΅Ρ‚Π΅ ΠΏΡ€ΠΈΡΠ²ΠΎΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΠΌΠ΅Π΅Ρ‚ Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присваивания.

Для Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ этого ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΎΠ³ΠΎ ввСдСния, ΠΏΠΎΠ·Π²ΠΎΠ»ΡŒΡ‚Π΅ ΠΌΠ½Π΅ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π΅Ρ‰Π΅ ΠΎΠ΄Π½Ρƒ Π²Π°Ρ€ΠΈΠ°Ρ†ΠΈΡŽ Π½Π° Ρ‚Π΅ΠΌΡƒ ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ. ΠžΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΈ API часто распрСдСляСт ΠΏΠ°ΠΌΡΡ‚ΡŒ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ свои собствСнныС ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ распрСдСлСния. Π­Ρ‚ΠΎ Π½Π΅ Π±Ρ‹Π»ΠΎ Π±Ρ‹ Π½Π°ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠ»ΠΎΡ…ΠΎ, Ссли Π±Ρ‹ Π½Π΅ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‚ ΠΎΡ‚ вас освобоТдСния памяти с использованиСм Ρ‚ΠΎΠΉ ΠΆΠ΅ самой ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ распрСдСлСния. Π’Π°ΠΊ, всякий Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ° Π²Ρ€ΡƒΡ‡Π°Π΅Ρ‚ Π½Π°ΠΌ Ρ‚Π°ΠΊΠΎΠΉ ΡΠΎΠΌΠ½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠ°ΠΊΠ΅Ρ‚, ΠΌΡ‹ ΠΎΠ±Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ Π΅Π³ΠΎ Π² ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ.

template <class T> class

SShellPtr {

public:

 ~SShellPtr() {

  Free();

  _malloc->Release();

 }

 T* weak operator->() { return _p; }

 T const* operator->() const { return _p; }

 operator T const* () const { return _p; }

 T const& GetAccess () const { return *_p; }

protected:

 SShellPtr() : _p(0) {

  // Obtain malloc here, rather than

  // in the destructor.

  // Destructor must be fail-proof.

  // Revisit: Would static IMalloc * _shellMalloc work?

  if (SHGetMalloc(&_malloc) == E_FAIL) throw Exception "Couldn't obtain Shell Malloc";

 }

 void Free() {

  if (_p != 0) _malloc->Free(_p);

 _p = 0;

 }

 T * _p;

 IMalloc* _malloc;

private:

 SShellPtr(SShellPtr const& p) {}

 void operator=(SShellPtr const & p) {}

};

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° использованиС Ρ€Π°Π½Π΅Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠ΅ΠΌΠ°: класс SShellPtr нСпосрСдствСнно Π½Π΅ ΠΏΡ€ΠΈΠ³ΠΎΠ΄Π΅Π½ для использования. Π’Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡ‚ Π½Π΅Π³ΠΎ подкласс ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² Π½Π΅ΠΌ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ конструктор.