wyjątki c++

0

cześć, w nauce c++ doszedłem do wyjątków i mam kilka pytań a dokładniej nie rozumiem do końca kiedy je stosować? czy są operacje w których jasno określone jest że, używając ich (tych operacji/funkcji) musimy użyć wyjątku? Jako przykład (nie wiem czy dobry) podam operator indeksowania [] dla klasy "bezpiecznej tablicy"
kod z obsługą wyjątku

int operator[] (int x)
        {
            try {
                if (x >= indeks) {
                    throw out_of_range("blad zakresu tablicy");
                }

                return tab[x];
            }

            catch(logic_error & e) {
                cout<< "wylapany wyjatek logic_error" <<endl;
                cout<< e.what() <<endl;
                return tab[indeks-1];
            }
        }

i bez wyjątku

int operator[] (int x)
        {
            if (x >= indeks) {
                cout<< "blad zakresu tablicy" <<endl;
                return tab[indeks-1];
            }

            return tab[x];
        }

Czytałem też, że wyjątki mają negatywny wpływ na wydajność programu wiec jak to jest z ich stosowaniem? Czy jeżeli możemy dana sytuacje obsłużyć/zabezpieczyć w inny sposób to znaczy że wyjątek nie jest potrzebny? Z tym że w bardzo wielu przypadkach można wykorzystać zwykła klasę z numerem błędu i np stringiem informującym co poszło nie tak? Proszę o krótkie wytłumaczenie tej kwestii

1

wyjątek. Czyli sytuacja wyjątkowa. Na przykład operator new wyrzuci Ci wyjątkiem jeżeli nie uda mu się stworzyć obiektu.
Ty np pisząc funkcje która coś zapisuję do pliku możesz śmiało użyć wyjątków? Dlaczego? Bo nie jesteś w stanie przewidzieć wszystkich opcji. (brak uprawnień do zapisu, brak miejsca na dysku, zła nazwa pliku itd). Jeżeli co kolwiek się źle powiedzie rzucasz wyjątkiem. Po co? Jak ktoś w przyszłości będzie korzystał z Twojej funkcji zapiszDoPliku będzie mógł złapać ten wyjątek i odpowiednio go obsłużyć.

Ogólnie dzięki wyjątkom program się nie crashuje (jeżeli wyjątek złapiesz) i zamiast crashu możesz coś poczynić jeżeli sytuacja wyjątkowa nastąpiła

dla operatora [] przy bezpieczniej tablicy wyjątek jest jak najbardziej na miejscu

ja korzystając z "BezpiecznejTablicy" cieszyłbym się jakby mi klasa rzucała wyjątkami jeżeli przekroczę indeks (żebym czasem nie mazał po nie swojej pamięci)

1

Wyjatki sie stosuje w sytuacjach, kiedy cos MOZE pojsc nie tak nie z naszej winy. Genialnym przykladem jest alokacja pamieci ;)
Do sprawdzania danych wejsciowych czy wyjsciowych funkcji zazwyczaj uzywa sie asercji lub tego typu mechanizmow.
Co do tego co przedstawiles to MOZESZ, ale nie MUSISZ masz wolna reke, w wiekszosci przypadkow da sie uniknac stosowania wyjatkow.
btw. bledny warunek wstawiles tak czy siak.

1

Wersja z wyjątkami jest nieporozumieniem, powinno to wyglądać tak:

int operator[] (size_t x)
  {
   if(x>=indeks) throw out_of_range("blad zakresu tablicy");
   return tab[x];
  }

Np masz funkcje:

int suma(Tablica &T)
  {
   int s=0;
   for(i=0;i<T.size();--i) s+=T[i]; // tu "niezamierzony" błąd jest --i zamiast ++i
   return s;
  }

Oraz jej wywołanie:

Tablica T(20);
try
  {
   cout<<suma(T)<<endl;
  }
catch(...)
  {
   cout<<"Coś sknociłeś w funkcji suma"<<endl;
  }

Owszem reakcja na wyjątek jest strasznie powolna, ale wyjątki to wyjątkowe sytuacje które nie powinny się zdarzać.

0

Wyjątki są przydatne jak np wywołujemy dużo funkcji które rzucają ten sam typ wyjątku. Możemy w jednym miejscu umieścić blok catch i wszystkie wyjątki jednego typu zostaną przechwycone. Jak byśmy używali sprawdzania znacznika błędu kod byłby dość nieczytelny bo za każdym razem musielibyśmy sprawdzać ifem czy nie nastąpił błąd.

1

no tak, wartości ujemnych nie brałem w ogóle pod uwage ;)
i słusznie, że nie brałeś ich pod uwagę (w warunku) bo indeks tablicy nie powinien być liczbą ujemną. Niesłuszne jest natomiast to, że do indeksowania tablicy stosujesz typ, który przechowuje wartości ujemne.
Użycie wyjątków np. przy indeskowaniu klas implementujących tablice jest wg mnie śmieszne bo jest to idotoodporność dla programisty, która sporo kosztuje. Programista sam powinien dbać o to aby nie przekroczyć zakresu dlatego stosowanie wyjątków w sytuacjach błędów logicznych programisty jest zbędne z perspektywy projektanta klasy. Taką koncepcje obrali również twórcy biblioteki standardowej c++ (w tym stl'a), która posiada znikomą obsługę błędów (chroni przede wszystkim przed błędami wykonania spowodowanymi przez środowisko wykonania programu bądź jego kontekst, czyli takimi, na które programista nie ma bezpośredniego wpływu). Oczywiście istnieją wersje biblioteki standardowej z obsługą błędów ale te dołączone do popularnych kompilatorów najczęściej jej nie posiadają - i słusznie. Gdy chcesz kontroli w określonym przypadku sam możesz ją zaimplementować opakowując odpowiednio w klasę elementy, które chcesz nadzorować.

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