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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π­Ρ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΠ΅ использованиС C++. 55 Π²Π΅Ρ€Π½Ρ‹Ρ… способов ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ структуру ΠΈ ΠΊΠΎΠ΄ Π²Π°ΡˆΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 33

Автор Π‘ΠΊΠΎΡ‚Ρ‚ ΠœΠ°ΠΉΠ΅Ρ€Ρ

static_cast<Window>(*this).onResize(); // Π² ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΠΎΠΌ классС;

// ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ *this ΠΊ Window,

// Π·Π°Ρ‚Π΅ΠΌ Π²Ρ‹Π·ΠΎΠ² Π΅Π³ΠΎ onResize;

// это Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚!

... // Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ спСцифичСской для

} // SpecialWindow части onResize

...

};


Π― Π²Ρ‹Π΄Π΅Π»ΠΈΠ» Π² этом ΠΊΠΎΠ΄Π΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ°. (Π­Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π² Π½ΠΎΠ²ΠΎΠΌ стилС, Π½ΠΎ использованиС старого стиля Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ мСняСт.) Как ΠΈ оТидаСтся, *this ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Ρ‚ΠΈΠΏΡƒ Window. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ onResize ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Π²Ρ‹Π·ΠΎΠ²Ρƒ Window::onResize. Π’ΠΎΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ эта функция Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Π½Π° для Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°! НСоТиданно, Π½Π΅ ΠΏΡ€Π°Π²Π΄Π° Π»ΠΈ? ВмСсто этого ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ привСдСния создаст Π½ΠΎΠ²ΡƒΡŽ, Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ копию части Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса *this ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ onResize для этой ΠΊΠΎΠΏΠΈΠΈ! ΠŸΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΉ Π²Ρ‹ΡˆΠ΅ ΠΊΠΎΠ΄ Π½Π΅ Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ Window::onResize для Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° с ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ спСцифичных для SpecialWindow дСйствий – ΠΎΠ½ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ Window::onResize для ΠΊΠΎΠΏΠΈΠΈ части Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΏΠ΅Ρ€Π΅Π΄ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ спСцифичных для SpecialWindow дСйствий для Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. Если Window::onResize ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ (Ρ‡Ρ‚ΠΎ Π²ΠΏΠΎΠ»Π½Π΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ onResize – Π½Π΅ константная функция-Ρ‡Π»Π΅Π½), Ρ‚ΠΎ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½. ВмСсто этого Π±ΡƒΠ΄Π΅Ρ‚ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Π° копия этого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. Однако Ссли SpecialWindow::onResize ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½ ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚. И Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ остаСтся Π² нСсогласованном состоянии, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ модификация Ρ‚ΠΎΠΉ Π΅Π³ΠΎ части, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚ Π±Π°Π·ΠΎΠ²ΠΎΠΌΡƒ классу, Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π°, Π° модификация части, ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‰Π΅ΠΉ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΠΎΠΌΡƒ классу, Π±ΡƒΠ΄Π΅Ρ‚.

РСшСниС ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ°, Π·Π°ΠΌΠ΅Π½ΠΈΠ² Π΅Π³ΠΎ Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΈΠΌΠ΅Π»ΠΈ Π² Π²ΠΈΠ΄Ρƒ. НСт нСобходимости Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ Ρ‚Ρ€ΡŽΠΊΠΈ с компилятором, заставляя Π΅Π³ΠΎ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ *this ΠΊΠ°ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса. Π’Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Π²Π΅Ρ€ΡΠΈΡŽ onResize Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса для Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. Π’Π°ΠΊ поступитС ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:


class SpecialWindow: public Window {

public:

virtual void onResize() {

Window::onResize(); // Π²Ρ‹Π·ΠΎΠ² Window::onResize Π½Π° *this

...

}

...

};


ΠŸΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ‚Π°ΠΊΠΆΠ΅ дСмонстрируСт, Ρ‡Ρ‚ΠΎ коль скоро Π²Ρ‹ ΠΎΡ‰ΡƒΡ‰Π°Π΅Ρ‚Π΅ ΠΆΠ΅Π»Π°Π½ΠΈΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ°, это Π·Π½Π°ΠΊ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Π²Ρ‹, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π½Π° Π»ΠΎΠΆΠ½ΠΎΠΌ ΠΏΡƒΡ‚ΠΈ. ОсобСнно это касаСтся ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° dynamic_cast.

ΠŸΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ Π²Π΄Π°Π²Π°Ρ‚ΡŒΡΡ Π² Π΄Π΅Ρ‚Π°Π»ΠΈ dynamic_cast, стоит ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΉ этого ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ довольно ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ. Π’Π°ΠΊ, ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅, ΠΎΠ΄Π½Π° ΠΈΠ· распространСнных Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΉ основана Π½Π° сравнСнии ΠΈΠΌΠ΅Π½ классов, прСдставлСнных строками. Если Π²Ρ‹ выполняСтС dynamic_cast для ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° класса, ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‰Π΅Π³ΠΎ ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΠΈ с ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½Ρ‹ΠΌ наслСдованиСм Π³Π»ΡƒΠ±ΠΈΠ½ΠΎΠΉ Π² Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ уровня, Ρ‚ΠΎ ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ dynamic_cast Π² Ρ‚Π°ΠΊΠΎΠΉ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠ±ΠΎΠΉΡ‚ΠΈΡΡŒ Π²Π°ΠΌ Π² Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ Π²Ρ‹Π·ΠΎΠ²Π° strcmp для сравнСния ΠΈΠΌΠ΅Π½ классов. Для Π±ΠΎΠ»Π΅Π΅ Π³Π»ΡƒΠ±ΠΎΠΊΠΎΠΉ ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΠΈ ΠΈΠ»ΠΈ Ρ‚Π°ΠΊΠΎΠΉ, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ имССтся мноТСствСнноС наслСдованиС, эта опСрация окаТСтся Π΅Ρ‰Π΅ Π±ΠΎΠ»Π΅Π΅ дорогостоящСй. Π•ΡΡ‚ΡŒ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρ‹, ΠΈΠ·-Π·Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ (ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ Π΄ΠΈΠ½Π°ΠΌΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²ΠΊΡƒ). Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Π² Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊ настороТСнности ΠΏΠΎ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡŽ ΠΊ привСдСниям Ρ‚ΠΈΠΏΠΎΠ² Π² ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ΅ Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΡ€ΠΎΡΠ²Π»ΡΡ‚ΡŒ особый скСптицизм, ΠΊΠΎΠ³Π΄Π° Ρ€Π΅Ρ‡ΡŒ ΠΈΠ΄Π΅Ρ‚ ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠΈ dynamic_cast Π² части ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, для ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ стоит Π½Π° ΠΏΠ΅Ρ€Π²ΠΎΠΌ мСстС.

ΠΠ΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ Π² dynamic_cast ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ появляСтся ΠΈΠ·-Π·Π° Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Π΅ Π² ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΠΎΠΌ классС, для ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ, ΠΊΠ°ΠΊ Π²Ρ‹ ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚Π΅, ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΠΎΠΌΡƒ классу, Π½ΠΎ ΠΏΡ€ΠΈ этом Ρƒ вас Π΅ΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ ΠΈΠ»ΠΈ ссылка Π½Π° Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ класс, посрСдством ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π½ΡƒΠΆΠ½ΠΎ ΠΌΠ°Π½ΠΈΠΏΡƒΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ. Π•ΡΡ‚ΡŒ Π΄Π²Π° основных способа ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ этой ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹.

ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ – ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Ρ‹ для хранСния ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ (часто Β«ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ…Β», см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 13) Π½Π° сами ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½Ρ‹Ρ… классов, Ρ‚ΠΎΠ³Π΄Π° ΠΎΡ‚ΠΏΠ°Π΄Π΅Ρ‚ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ ΠΌΠ°Π½ΠΈΠΏΡƒΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ этими ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ Ρ‡Π΅Ρ€Π΅Π· интСрфСйсы Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса. НапримСр, Ссли Π² нашСй ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΠΈ Window/SpecialWindow Ρ‚ΠΎΠ»ΡŒΠΊΠΎ SpecialWindow ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΌΠ΅Ρ€Ρ†Π°Π½ΠΈΠ΅ (blinking), Ρ‚ΠΎ вмСсто:


class Window { ...};

class SpecialWindow {

public:

void blink();

...

};

typedef // см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 13

std::vector<std::tr1::shared_ptr<Window>>VPW; // ΠΎ tr1::shared_ptr

VPW winPtrs;

...

for (VPW::iterator iter = winPtrs.begin(); // Π½Π΅ΠΆΠ΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΊΠΎΠ΄:

iter!=winPtrs.end(); // примСняСтся dynamic_cast

++iter){

if(SpecialWindow psw = dynamic_cast<SpecialWindow>(iter->get()))

psw->blink();

}


ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠΉΡ‚Π΅ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ:


typedef std::vector<std::tr1::shared_ptr<SpecialWindow>> VPSW;

VPSW winPtrs;

...

for (VPSW::iterator iter = winPtrs.begin(); // это Π»ΡƒΡ‡ΡˆΠ΅:

iter != winPtrs.end(); // Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ dynamic_cast

++iter)

(*iter)->blink();


ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, Ρ‚Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Π½Π΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ Π²Π°ΠΌ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ всСх Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½Ρ‹Ρ… ΠΎΡ‚ Window классов Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΈ Ρ‚ΠΎΠΌ ΠΆΠ΅ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π΅. Π§Ρ‚ΠΎΠ±Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ Ρ‚ΠΈΠΏΠ°ΠΌΠΈ ΠΎΠΊΠΎΠ½ ΠΈ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ ΠΏΠΎ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡŽ ΠΊ Ρ‚ΠΈΠΏΠ°ΠΌ, Π²Π°ΠΌ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡ‚ΡŒΡΡ нСсколько ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΎΠ².

ΠΠ»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π°, которая ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ ΠΌΠ°Π½ΠΈΠΏΡƒΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ всСх Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½Ρ‹Ρ… ΠΎΡ‚ Window классов Ρ‡Π΅Ρ€Π΅Π· интСрфСйс Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса, β€“ это ΠΏΡ€Π΅Π΄ΡƒΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π² Π±Π°Π·ΠΎΠ²ΠΎΠΌ классС, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ позволят Π²Π°ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π²Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ. НапримСр, хотя Ρ‚ΠΎΠ»ΡŒΠΊΠΎ SpecialWindow ΡƒΠΌΠ΅Π΅Ρ‚ ΠΌΠ΅Ρ€Ρ†Π°Ρ‚ΡŒ, ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ, ΠΈΠΌΠ΅Π΅Ρ‚ смысл ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π² Π±Π°Π·ΠΎΠ²ΠΎΠΌ классС ΠΈ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ Ρ‚Π°ΠΌ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, которая Π½Π΅ Π΄Π΅Π»Π°Π΅Ρ‚ Π½ΠΈΡ‡Π΅Π³ΠΎ:


class Window {

public:

virtual void blink() {} // рСализация ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ – пустая

... // опСрация, см. Π² ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 34 – ΠΏΠΎΡ‡Π΅ΠΌΡƒ

}; // Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ

// ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ Π½Π΅ΡƒΠ΄Π°Ρ‡Π½ΠΎΠΉ ΠΈΠ΄Π΅Π΅ΠΉ

class SpecialWindow: public Window {

public:

virtual void blink() {...}

...

};

typedef std::vector<std::tr1::shared_ptr<Window>>VPW;

VPW winPtrs; // ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ содСрТит

// (ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π°) всС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅

... // Ρ‚ΠΈΠΏΡ‹ ΠΎΠΊΠΎΠ½

for(VPW::iterator iter = winPtrs.begin();

iter != winPtrs.end();

++iter) // dynamic_cast Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ

(*iter)->blink();


Ни ΠΎΠ΄ΠΈΠ½ ΠΈΠ· этих ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠ² – с ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ бСзопасных ΠΏΠΎ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡŽ ΠΊ Ρ‚ΠΈΠΏΠ°ΠΌ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΎΠ² ΠΈΠ»ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ΠΌ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π²Π²Π΅Ρ€Ρ… ΠΏΠΎ ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΠΈ – Π½Π΅ являСтся ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌΡ‹ΠΌ, Π½ΠΎ Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ… случаях ΠΎΠ½ΠΈ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ ΠΏΠΎΠ»Π΅Π·Π½ΡƒΡŽ Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Ρƒ dynamic_cast. ΠŸΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ΡΡŒ ΠΈΠΌΠΈ, ΠΊΠΎΠ³Π΄Π° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ.

Но Π²ΠΎΡ‚ Ρ‡Π΅Π³ΠΎ стоит ΠΈΠ·Π±Π΅Π³Π°Ρ‚ΡŒ всСгда – это каскадов ΠΈΠ· ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² dynamic_cast, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Ρ‡Π΅Π³ΠΎ-Ρ‚ΠΎ Π²Ρ€ΠΎΠ΄Π΅ Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°:


class Window {...};

... // здСсь ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½Ρ‹Π΅ классы

typedef std::vector<std::tr1::shared_ptr<Window>> VPW;

VPW winPtrs;

...

for (VPW::iterator iter = winPtrs.begin(); iter != winPtrs.end(); ++iter)

{

if (SpecialWindow1 *psw1=

dynamic_cast<SpecialWindow1>(iter->get())) {...}

else if (SpecialWindow2 *psw2=

dynamic_cast<SpecialWindow2>(iter->get())) {...}

else if (SpecialWindow2 *psw2=

dynamic_cast<SpecialWindow2>(iter->get())) {...}

...

}


Π’ этом случаС гСнСрируСтся ΠΎΠ±ΡŠΠ΅ΠΌΠ½Ρ‹ΠΉ ΠΈ ΠΌΠ΅Π΄Π»Π΅Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄, ΠΊ Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ ΠΎΠ½ нСстабилСн, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΠΈ классов Window вСсь этот ΠΊΠΎΠ΄ Π½ΡƒΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅ΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π½Π° ΠΏΡ€Π΅Π΄ΠΌΠ΅Ρ‚ обновлСния. НапримСр, Ссли добавится Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½Ρ‹ΠΉ класс, Ρ‚ΠΎ вСроятно, придСтся Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π΅Ρ‰Π΅ ΠΎΠ΄Π½Ρƒ Π²Π΅Ρ‚Π²ΡŒ Π² ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ if. ΠŸΠΎΠ΄ΠΎΠ±Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ ΠΏΠΎΡ‡Ρ‚ΠΈ всСгда Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΌΠ΅Π½Π΅Π½ Ρ‡Π΅ΠΌ-Ρ‚ΠΎ Π½Π° основС Π²Ρ‹Π·ΠΎΠ²Π° Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ.

Π’ Ρ…ΠΎΡ€ΠΎΡˆΠ΅ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Π½Π° C++ привСдСния Ρ‚ΠΈΠΏΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ ΠΎΡ‡Π΅Π½ΡŒ Ρ€Π΅Π΄ΠΊΠΎ, Π½ΠΎ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΠΎΡ‚ΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒΡΡ ΠΎΡ‚ Π½ΠΈΡ… Ρ‚ΠΎΠΆΠ΅ Π½Π΅ стоит. Π’Π°ΠΊ, ΠΏΠΎΠΊΠ°Π·Π°Π½Π½ΠΎΠ΅ Π²Ρ‹ΡˆΠ΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ int ΠΊ double являСтся Ρ€Π°Π·ΡƒΠΌΠ½Ρ‹ΠΌ, хотя ΠΈ Π½Π΅ Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹ΠΌ (ΠΊΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ пСрСписан с объявлСниСм Π½ΠΎΠ²ΠΎΠΉ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Ρ‚ΠΈΠΏΠ° double, ΠΈΠ½ΠΈΡ†ΠΈΠΈΡ€ΡƒΠ΅ΠΌΠΎΠΉ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ x). Как ΠΈ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ ΡΠΎΠΌΠ½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… конструкций, привСдСния Ρ‚ΠΈΠΏΠΎΠ² Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ насколько Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ ΠΎΠ½ΠΈ ΠΏΠΎΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ Π²Π½ΡƒΡ‚Ρ€ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Ρ‡Π΅ΠΉ интСрфСйс скрываСт ΠΎΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ Ρ‚Π΅ нСкрасивыС Π΄Π΅Π»Π°, Ρ‡Ρ‚ΠΎ творятся Π²Π½ΡƒΡ‚Ρ€ΠΈ.

Π§Ρ‚ΠΎ слСдуСт ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ

β€’ Π˜Π·Π±Π΅Π³Π°ΠΉΡ‚Π΅ насколько Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠΉ Ρ‚ΠΈΠΏΠΎΠ², особСнно dynamic_cast, Π² ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π½ΠΎΠΌ ΠΏΠΎ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΊΠΎΠ΄Π΅. Если Π΄ΠΈΠ·Π°ΠΉΠ½ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ привСдСния, ΠΏΠΎΠΏΡ‹Ρ‚Π°ΠΉΡ‚Π΅ΡΡŒ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Ρƒ, Π³Π΄Π΅ Ρ‚Π°ΠΊΠΎΠΉ нСобходимости Π½Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚.

β€’ Когда ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ, ΠΏΠΎΡΡ‚Π°Ρ€Π°ΠΉΡ‚Π΅ΡΡŒ ΡΠΊΡ€Ρ‹Ρ‚ΡŒ Π΅Π³ΠΎ Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Π’ΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ смогут Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ вмСсто помСщСния привСдСния Π² ΠΈΡ… собствСнный ΠΊΠΎΠ΄.

β€’ ΠŸΡ€Π΅Π΄ΠΏΠΎΡ‡ΠΈΡ‚Π°ΠΉΡ‚Π΅ привСдСния Π² стилС C++ старому ΡΡ‚ΠΈΠ»ΡŽ. Π˜Ρ… Π»Π΅Π³Ρ‡Π΅ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ, ΠΈ ΠΎΠ½ΠΈ Π±ΠΎΠ»Π΅Π΅ ΠΈΠ·Π±ΠΈΡ€Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹.

ΠŸΡ€Π°Π²ΠΈΠ»ΠΎ 28: Π˜Π·Π±Π΅Π³Π°ΠΉΡ‚Π΅ возвращСния «дСскрипторов» Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ…

ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚Π΅ Π½Π°Π΄ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ, ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΠΌ Π΄Π΅Π»ΠΎ с ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊΠ°ΠΌΠΈ. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ прСдставлСн своим Π»Π΅Π²Ρ‹ΠΌ Π²Π΅Ρ€Ρ…Π½ΠΈΠΌ ΡƒΠ³Π»ΠΎΠΌ ΠΈ ΠΏΡ€Π°Π²Ρ‹ΠΌ Π½ΠΈΠΆΠ½ΠΈΠΌ. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Rectangle оставался ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚Π½Ρ‹ΠΌ, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ описаниС ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰ΠΈΡ… Π΅Π³ΠΎ Ρ‚ΠΎΡ‡Π΅ΠΊ слСдуСт вынСсти ΠΈΠ· Rectangle Π²ΠΎ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½ΡƒΡŽ структуру:


class Point { // класс, ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΠΉ Ρ‚ΠΎΡ‡ΠΊΠΈ

public:

Point(int x, int y);