Wyjatki zastosowane w operatorach

Odpowiedz Nowy wątek
2018-06-13 16:29
0

Cześć, mam pewien dylemat, tworze sobie swój własny wyjątek, z nadpisana metoda wirtualna what() z klasy exception (obowiazkowo musze tak zrobic),

class PozaZasiegiem : public exception
{
public:
    char const* what() const override
    {
        return "Poza zasiegiem";
    }
};

chce ten wyjatek wyrzucić w przypadku gdy użytkownik odwoła się w niewłaściwy sposób podczas podawania indexu tablicy dla obiektu klasy "Tablica", tutaj przeciążyłem operator[]

    int & operator[] (int index_tablicy) 
    {
        try
        {
            if (index_tablicy < 0 || index_tablicy >= rozmiar)
                throw PozaZasiegiem();
        }
        catch (const std::exception& ex)
        {
            cerr << ex.what();
        }
 
        cout << " zwracam wartosci: " << tablica_liczb[index_tablicy] << endl;
        return tablica_liczb[index_tablicy];
    }

Pytanie czy te bloki sa we wlasciwym miejscu? Bo wyrzuca mi wyjatek ale wciaz operator zwraca mi wartosc, a tak nie powinno byc.

edytowany 1x, ostatnio: darthachill, 2018-06-13 16:33

Pozostało 580 znaków

2018-06-13 16:34
kq
1

Operator rzuca wyjątek, a nie go łapie. Łapie go użytkownik, czyli programista korzystający z biblioteki (albo nie, i wtedy program leci).

Btw, do Twojego celu lepiej dziedziczyć z std::out_of_range. No i pisać po angielsku ​:​)


Pozostało 580 znaków

2018-06-13 16:44
0

zadanie ze studiów, też jestem za pisaniem po angielsku, ale język narzucony z tresci ;)... Masz racje mozna wykorzystac std::out_of_range, ale tutaj chodzi aby nauczyć sie korzystać z klasy exception
Nadal nie rozumiem co zrobić z tym blokiem. mam go przenieść poza operator i klase ? I w mainie (w moim wypadku) w każdym miejscu kiedy użytkownik mógłby wykorzystać nieprawidłowo operator[], to wtedy dawać bloki try i catch? No ale straszna redundancja... Myślę ze chodziło ci o coś innego, ale nie wiem co ;).

int main()
{
    const int rozmiar = 3;
    Tablica nasza_tablica(rozmiar);
 
    try
    {
        nasza_tablica[10] = 4;
    }
    catch (const std::exception& ex)
    {
        cout << ex.what();
    }
 
    getchar();
}
    int & operator[] (int index_tablicy)
    {
        if (index_tablicy < 0 || index_tablicy >= rozmiar)
            throw PozaZasiegiem();
 
        cout << " zwracam wartosci: " << tablica_liczb[index_tablicy] << endl;
        return tablica_liczb[index_tablicy];
    }
edytowany 2x, ostatnio: darthachill, 2018-06-13 16:57

Pozostało 580 znaków

2018-06-13 17:08
kq
2

Wyjątek rzuca operator[], a użytkownik go ewentualnie łapie. Na przykładzie std::vector i .at(), żeby nie było copy-paste ;​)

void process(vector<int>& foo, int id)
{
    foo.at(id) *= 2;
}
 
int main()
{
    vector<int> foos{1,2,3,4};
    int i;
    cin >> i;
    try {
        process(foos, i);
    } catch(std::exception const& e) {
        cout << "error: " << e.what() << endl;
    }
    for(auto i : foos)
        cout << i << ", ";
    cout << endl;
}
 

Generalnie, wyjątki łapiesz "gdzieś wyżej" w łańcuchu wywołań, a nie bezpośrednio w miejscu użycia. Inaczej mógłbyś napisać zwykłego ifa, aby sprawdzić warunki.


edytowany 1x, ostatnio: kq, 2018-06-13 17:14

Pozostało 580 znaków

2018-06-13 17:23
0

ok, czyli jednak jest tak jak napisalem, wszedzie tam gdzie wystapi jakis blad nalezy stosowac bloki try i catch, nie w samej metodzie ale przed jej wywolaniem np. tutaj przy tworzeniu obiektu, kiedy możemy podać błędny rozmiar tablicy, oraz w przypadku gdy możemy odwołać się do elementu z poza zakresu

int main()
{
    int rozmiar;
    cin >> rozmiar;
    Tablica tablica;
 
    try
    {
        // zalozmy ze uzytkownik podal rozmiar z blednego zakresu np. < 0
        // wtedy w konstruktorze wyrzucamy wyjatek out_of_range
        tablica = Tablica(rozmiar);
    }
    catch (const std::exception& ex)
    {
        // i lapiemy go w catchu oraz wywloujemy metode 
        ex.what();
    }
 
    int wybrany_element;
    cin >> wybrany_element;
 
    try
    {
        // zalozmy ze uzytkownik odwolal sie do  elementu poza zakresem
        tablica[wybrany_element] = 4;
    }
    catch (const std::exception& ex)
    {
        cout << ex.what();
    }
 
    getchar();
}
edytowany 1x, ostatnio: darthachill, 2018-06-13 17:24

Pozostało 580 znaków

2018-06-14 09:34
darthachill napisał(a):

ok, czyli jednak jest tak jak napisalem, wszedzie tam gdzie wystapi jakis blad nalezy stosowac bloki try i catch

NIE! try catch wstawiasz tylko tam gdzie chcesz obsłużyć potencjalne błędy.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 1x, ostatnio: MarekR22, 2018-06-14 10:19

Pozostało 580 znaków

2018-06-14 09:44
0

wszedzie tam gdzie wystapi jakis blad nalezy stosowac bloki try i catch

C++ to nie C# gdzie nawet wyjście poza granicę tablicy rzuca wyjątkiem. W C++ trzeba wiedzieć jakie elementy języka rzucają wyjątek, a jakie nie; ot taka spuścizna po C, gdzie wyjątków w ogóle nie było.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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

Robot: CCBot