Tugallanmagan istisnolar. Yuqorida biz murojaat qiluvchiga (yoki murojaatlar to'plamida "yuqorida joylashgan" boshqa funktsiyaga) qanday qilib istisnolardan foydalanishni topshirishni bilib oldik. Quyidagi misolda mySqrt () funksiyasi istisno qiladi va kimdir buni hal qiladi deb taxmin qiladi. Lekin hech kim buni qilmasa nima bo'ladi?
Mana main() funksiyasidagi try blokisiz sonning kvadrat ildizini hisoblash uchun dasturimiz:
#include
#include using namespace std;
double mySqrt(double a)
{
if (a < 0.0)
throw "Manfiy sondan ildiz olib bo'lmaydi";
return sqrt(a);
}
int main()
{
cout << "Son kiriting: ";
double a;
cin >> a;
double d = mySqrt(a);
cout << "Natija:" << a << " ning kvadrat ildizi " << d << '\n';
return 0;
}
Aytaylik, foydalanuvchi -5 kiritdi va mySqrt (-5) istisno qiladi. mySqrt () funktsiyasi o'z istisnolarini o'z-o'zidan hal qilmaydi, shuning uchun stek bo'shashishni boshlaydi va bajarish nuqtasi yana main () ga o'tadi. Lekin, main () da ham istisno ishlovchisi mavjud emasligi sababli, main () va butun dasturning bajarilishi tugatiladi.
main() ishlov berilmagan istisno bilan ishlashni tugatsa, operatsion tizim odatda bizga ishlov berilmagan istisno xatosi haqida xabar beradi. Buni qanday amalga oshirishi har bir operatsion tizimga alohida bog'liq:
yoki xato xabarini ko'rsatadi;
yoki xato bilan dialog oynasini ochadi;
yoki shunchaki halokat.
18-MA’RUZA. KUTILMAGAN ISTISNOLI HOLATLARNI QAYTA ISHLASH. ISTISNOLI HOLATLARNI KONSTRUKTORLARDA GENERASIYA QILISH. ISTISNOLI HOLATLAR VA VORISLIK.
Barcha turdagi istisnolar uchun qayta ishlovchilar. Va endi topishmoq: "Funktsiyalar har qanday ma'lumot turidagi istisnolarni tashlashi mumkin va agar istisno ushlanmasa, u stekni bo'shatadi va butun dasturni potentsial ravishda to'xtatadi. Biz funktsiyalarni ularning bajarilishini bilmasdan chaqira oladigan bo'lsak (va shuning uchun ular qanday istisnolar qo'yishi mumkin), buni qanday oldini olishimiz mumkin? "
Yaxshiyamki, C ++ tili bizga barcha turdagi istisnolarni aniqlash / boshqarish mexanizmini taqdim etadi - catch-all ishlov beruvchi. Hammasini ushlab turadigan ishlov beruvchi oddiy catch bloki bilan bir xil ishlaydi, faqat ma'lum bir ma'lumot turidagi istisnolarni ko'rib chiqish o'rniga u ma'lumotlar turi sifatida uchta nuqtadan (...) foydalanadi va biz allaqachon bilganimizdek, … istalgan turdagi ma'lumotlarning argumentlarini funksiyaga o'tkazish uchun ishlatilishi mumkin. Shu nuqtai nazardan, ular har qanday turdagi ma'lumotlarning istisnolarini ifodalaydi. Mana oddiy misol:
#include int main()
{
try
{
throw 7; // int tipidagi istisno genratsiya qilinadi
}
catch (double a)
{
cout << "Biz double turidagi istisnoni ushladik: " << a << '\n';
}
catch (...) // catch-all
{
cout << "Biz aniqlanmagan turdagi istisnoni qo'lga oldik!\n";
}
}
int uchun maxsus catch ishlov beruvchisi mavjud emasligi sababli, catch-all ishlov beruvchi bu istisnoni ushlaydi. Shunday qilib, natija:
“Biz aniqlanmagan turdagi istisnoni qo'lga oldik!”
Hammasini ushlab turuvchi tutqich bloklari zanjirida oxirgi bo'lishi kerak. Shunday qilib, istisnolar birinchi navbatda ma'lum ma'lumotlar turlariga moslashtirilgan (agar ular umuman mavjud bo'lsa) ushlagichlar tomonidan ushlanishi mumkin. Bu boshqa kompilyatorlar haqida Visual Studio'da nazorat qilinadi - bunday cheklov mavjudligiga ishonchim komil emas.