Wyjatki zastosowane w operatorach

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.

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 ​:​)

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];
	}
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.

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();
}
3
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.

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.

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