Konstruktorlar muvaffaqiyatsizlikka uchraganda. Konstruktorlar - bu istisnolar juda foydali bo'lishi mumkin bo'lgan sinflarning yana bir qismi. Agar konstruktor ishlamagan bo'lsa, obyektni yaratish mumkin emasligini ko'rsatadigan istisnoni tashlang. Obyekt yaratish to'xtatiladi va destruktor hech qachon bajarilmaydi (esda tuting, bu sizning konstruktoringiz istisno qilishdan oldin xotirani o'zi tozalashi kerakligini anglatadi).
Istisno sinflar. Asosiy ma'lumotlar turlaridan (masalan, int) istisno turlari sifatida foydalanishning asosiy muammolaridan biri ularning tabiatan aniqlanmaganligidir. try blokida bir nechta iboralar yoki funksiya chaqiruvlari mavjud bo'lganda istisno nimani anglatishining noaniqligi yanada jiddiyroq muammodir:
//ArrayInt uchun [] qayta yuklanish operatoridan foydalanish
try
{
int *value = new int(array[index1] + array[index2]);
}
catch (int value)
{
// Biz bu yerda qanday istisnolarni ushlaymiz?
}
Ushbu misolda, agar biz int tipidagi istisnoni qo'lga kiritsak, u bizga nimani aytadi? Indeks bekor qilinganmi? + operatori butun sonning to'lib ketishiga sabab bo'ldimi yoki xotira yetishmasligi tufayli yangi operator ishlamay qoldimi? Muvaffaqiyatsizlik SABABini ko'rsatadigan const char * istisnolarini qo'yishimiz mumkin bo'lsa-da, bu har xil manbalardagi istisnolarni boshqacha ko'rib chiqishimizga xalaqit beradi.
Ushbu muammoni hal qilishning bir usuli istisno sinflaridan foydalanishdir. Istisno sinf istisno sifatida chiqarilgan oddiy sinfdir. Keling, ArrayInt bilan foydalanish uchun oddiy istisno sinfini yarataylik:
#include
using namespace std;
class ArrayException
{
private:
string m_error;
public:
ArrayException(string error)
{
m_error = error;
}
const char* getError() { return m_error.c_str(); }
};
Mana to’liq dastur:
#include
#include
using namespace std;
class ArrayException
{
private:
string m_error;
public:
ArrayException(string error)
: m_error(error)
{
m_error = error;
}
const char* getError() { return m_error.c_str(); }
};
class ArrayInt
{
private:
int m_data[4]; // misolning soddaligi uchun massiv uzunligi sifatida 4 qiymatini belgilaymiz
public:
ArrayInt() {}
int getLength() { return 4; }
int& operator[](const int index)
{
if (index < 0 || index >= getLength())
throw ArrayException("Noto'g'ri indeks");
return m_data[index];
}
};
int main()
{
ArrayInt array;
try
{
int value = array[7];
}
catch (ArrayException &exception)
{
cerr << "Massivda istisno yuz berdi (" << exception.getError() << ")\n";
}
}
Bunday sinfdan foydalanib, biz yuzaga kelgan muammoning tavsifini qaytaradigan istisnoni tashlashimiz mumkin, bu bizga aynan nima noto'g'ri bo'lganini ko'rsatadi. Va, ArrayException noyob turdagi bo'lgani uchun, biz uni mos ravishda boshqarishimiz mumkin (boshqa istisnolar kabi emas).
Esda tutingki, istisno ishlovchilarida istisno sinfi obyektlari qiymat bo'yicha emas, balki mos yozuvlar bo'yicha olinishi kerak. Bu kompilyatorga qimmat operatsiya bo'lgan istisno nusxasini yaratishga yo'l qo'ymaydi (ayniqsa, istisno sinf obyekti bo'lsa) va avlod istisno sinflari bilan ishlashda obyektlarni kesishning oldini oladi. Agar jiddiy sabab bo'lmasa, manzilga o'tkazishdan foydalanmaslik yaxshiroqdir.
Do'stlaringiz bilan baham: |