Sobes.tech
Junior

Czym są wyjątki w C++?

sobes.tech AI

Odpowiedź od AI

Mechanizm obsługi sytuacji anormalnych (błędów), które występują podczas wykonywania programu. Pozwala oddzielić kod odpowiedzialny za logikę programu od kodu obsługi błędów.

Słowa kluczowe:

  • try: Definiuje blok kodu, w którym mogą wystąpić wyjątki.
  • catch: Definiuje blok kodu, który jest wykonywany, gdy wystąpi określony typ wyjątku.
  • throw: Generuje (tworzy) wyjątek. Typ wyjątku może być dowolnym obiektem.

Zasada działania:

  1. Kod, który może wywołać błąd, umieszcza się w bloku try.
  2. Jeśli w bloku try wystąpi wyjątek (wygenerowany za pomocą throw), normalne wykonanie programu zostaje przerwane.
  3. System szuka odpowiedniego bloku catch, zdolnego obsłużyć wygenerowany wyjątek (według typu).
  4. Jeśli zostanie znaleziony odpowiedni catch, jego kod jest wykonywany.
  5. Jeśli nie zostanie znaleziony odpowiedni catch na bieżącym poziomie wywołań, wyjątek "rozprzestrzenia się" w górę stosu wywołań, aż zostanie znaleziona odpowiednia funkcja obsługi (lub program zakończy się niepoprawnie).

Przykład:

#include <iostream>
#include <stdexcept> // Dla standardowych typów wyjątków

int divide(int a, int b) {
    if (b == 0) {
        throw std::runtime_error("Dzielenie przez zero!"); // Generujemy wyjątek
    }
    return a / b;
}

int main() {
    try {
        int result = divide(10, 0); // Wywołujemy funkcję, która może rzucić wyjątek
        std::cout << "Wynik: " << result << std::endl; // Ta linijka nie zostanie wykonana
    } catch (const std::runtime_error& e) { // Łapiemy wyjątek typu std::runtime_error
        std::cerr << "Błąd: " << e.what() << std::endl; // Obsługujemy wyjątek
    } catch (...) { // Łapiemy dowolny inny wyjątek (wielokropek)
        std::cerr << "Wystąpił nieznany błąd." << std::endl;
    }

    std::cout << "Program kontynuuje po obsłudze błędu." << std::endl;
    return 0;
}

Zalety:

  • Oddzielenie logiki od obsługi błędów.
  • Uproszczenie głównego przepływu kodu.
  • Możliwość obsługi błędów na różnych poziomach hierarchii wywołań.

Wady:

  • Może wpływać na wydajność (z powodu propagacji stosu).
  • Trudność w zrozumieniu przepływu wykonania przy wielu wyjątkach.
  • Nieprawidłowe użycie może prowadzić do wycieków zasobów (jeśli zasoby nie są zwalniane przy wystąpieniu wyjątku przed ich poprawnym zwolnieniem).

Do bezpiecznej pracy z zasobami w obecności wyjątków często używa się RAII (Resource Acquisition Is Initialization) i inteligentnych wskaźników.