Przy obsłudze błędów korzystamy z klauzul try/catch (Listing 1). Wyrzucenie wyjątku danej klasy następuje po wywołaniu instrukcji throw (Listing 2).
Listing 1 - main.cpp - driver do testowania obsługi błędów
#include <iostream>
#include "stack.h"
using namespace std;
int main(void)
{
try
{
Stack<int> s(-1);
}
catch(BadSize e)
{
cout << e.getMessage() << endl;
}
}
Listing 2 - klasa błędów i klasa korzystająca z obsługi błędów
#include <stdio.h>
#include <string.h>
#define maxMessageSize 100
class Error
{
public:
Error()
{
message=new char[maxMessageSize];
sprintf(message,"Unknown error");
}
char * getMessage() {return message;}
protected:
char *message;
};
class BadSize : public Error
{
public:
BadSize() { sprintf(message,"Bad size");}
};
class HeapFail : public Error
{
public:
HeapFail() { sprintf(message,"Heap fail");}
};
template <class T>
class Stack
{
public:
Stack(int max);
~Stack(void);
private:
T *stack;
int top;
const int maxSize;
};
template <class T>
Stack<T>::Stack(int max) : maxSize(max)
{
if (max<=0)
throw BadSize();
else if ((stack=new T[max])==0)
throw HeapFail();
top=-1;
}
template <class T>
Stack<T>::~Stack(void)
{
delete [] stack;
}
Rozważmy przykład funkcji, używanej do obsługi pakietów w aplikacji sieciowej:
void ReceivePacket(Packet *pack,Connection *c)
{
switch (pack->Type())
{
case controlPack:
//...
break;
case dataPack:
//...
break;
case diagnosePack:
//...
break;
default:
//...
}
}
Przypuśćmy, że chcemy obsłużyć następujące rodzaje błędów w funkcji ReceivePacket:
Połączenie c jest aktywne/nieaktywne. Connection::Active() zwraca wartość true/false
Transmisja pakietu przebiegła poprawnie/niepoprawnie. Packet::Valid() zwraca wartość true/false
Typ pakietu jest znany (w przeciwnym wypadku wykonywane są instrukcje w bloku default
Proszę zdefiniować klasy błędów do obsługi powyższych wyjątków. Proszę przepisać funkcję ReceivePacket w ten sposób, aby wyrzucała wyjątki w przypadku napotkania błędów. Proszę zaimplementować klasy konieczne do zademonstrowania obsługi błędów.