[c++] obsluga wyjatkow

0

Czytam wlasnie o obsludze wyjatkow i nastrafilem na taki kod:

template<class T, int sz = 1> class PWrap {
  T* ptr;
public:
  class RangeError {}; // Exception class
  PWrap() {
    ptr = new T[sz];
    cout << "PWrap konstruktor" << endl;
  }
  ~PWrap() {
    delete[] ptr;
    cout << "PWrap destruktor" << endl;
  }
  T& operator[](int i) throw(RangeError) {
    if(i >= 0 && i < sz) return ptr[i];
    throw RangeError();
  }
};

chodzi mi o przeciazony operator []. Czy moglby mi ktos wyjasnic co robi throw(RangeError) przed cialem funkcji? Bez tego program mi sie skompilowal i zadzialal tak jak z throw.

0

to powoduje, ze operator [] moze rzucić tylko wyjątek RangeError - żadnego innego. Takie ograniczenie :-)

0

Wiec jakim cudem udalo mi sie wyrzucic wyjatek RangeError2() ?

T& operator[](int i) throw(RangeError) 
{
    if(i >= 0 && i < sz)   throw RangeError();
    else throw RangeError2();
}

dodam moze, ze to kompilator VS

0

co to znaczy, ze Ci sie udalo?
program sie skompiluje, ale rzucenie wyjatkiem spoza listy powinno wywolac funkcje unexpected, co wywali Twoj program :-) (standardowo ofc).

VS zawsze robil dziwne rzeczy, np.
for(int i = 0; i < 10; i++)
cout << i << endl;
cout << i; // tu i nie istnieje :-/ ale nie w VC

moze to po prostu ignoruje ;-)

Albo cos sie zmienilo od kiedy sie tego uczylem :-)

0

Zadna funkcja unexpected nie jest wywolywana (chyba, bo nie wiem co to jest ... jeszcze;) ), wyjatki przechwytuje w takim bloku:

try 
{
   . . .   // tu sie cos dzieje
}
catch(RangeError&)  { cout << "blad zakresu 1" << endl; }
catch(RangeError2&) { cout << "blad zakresu 2" << endl; }
catch(RangeError3&) { cout << "blad zakresu 3" << endl;	}

i wszystko wypisuje sie (nie)zgodnie z oczekiwaniami, tzn. dostaje na konsoli blad zakresu 2 [???]

0
#include <iostream>
#include <cmath>
#include <stdexcept>
using namespace std;


double logarytm(double x) throw (out_of_range)      /* 1 */
{
    if (x <= 0) throw out_of_range("Logarytm z liczby ujemnej ;-/");
//    throw runtime_error("runtime error");         /* 2 */
    return log10(x);
}

int main()
{
    double x = 0;
    double y = 0;

    try
    {
        x = logarytm(100);
        y = logarytm(-10);
    }
    catch(out_of_range)
    {
        cerr << "Mozna logarytmowac tylko dodatnie liczby!!!!" << endl;;
    }
    catch(runtime_error)
    {
        cerr << "Wystapil runtime error" << endl;
    }

    cout << x << " " << y << endl;
}

Pokombinuj z komentowaniem linii /* 1 / oraz / 2 */. (w 1 oczywiscie chodzi o to od pierwszego ')' )
Zwroc uwage, ze jezeli jest throw w 1 to mimo, ze w catch jest runtime to nie jest on obslugiwany - aplikacja sie wywala. Jezeli wyrzucisz throw z 1 to jest ok (przechodzi do bloku catch)

// Edit:
Nie przejmuj sie, jezeli to nie dziala or sth. w praktyce jeszcze nigdy tego nie uzylem (z wyjatkiem tego przykladu przed chwila) :-) Po prostu trzeba by konsekwentnie przy kazdej funkcji/metodzie dopisywac liste rzucanych wyjatkow, w innym przypadku doprowadzasz do dosc glupich sytuacji, kiedy wyjatek nie moze byc obsluzony i zawsze wywala program.

0

double logarytm(double x) throw (out_of_range)      /* 1 */
{
    if (x <= 0) throw out_of_range("Logarytm z liczby ujemnej ;-/");
    throw runtime_error("runtime error");         /* 2 */
    return log10(x);
}

taki kod w visualu skompilowal sie bez problemu tzn wyjatek zostal obsluzony, nie poszlo za to w dev-c++ .... microsoft i ich standardy ;)

0

VC++ nie ma tego zaimpelemntowanego. Nic na to nie poradzimy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1