|
| 1 | +/** |
| 2 | + * @file basic.cpp |
| 3 | + * @author Xuhua Huang |
| 4 | + * @brief Basic exception handling example |
| 5 | + * The C++ standard provides a base class specifically designed to declare objects to be thrown as exceptions |
| 6 | + * and to be caught by handlers. This class is called std::exception and is defined in the <exception> header file. |
| 7 | + * The std::exception class has a virtual member function called what() that returns a C-style string describing |
| 8 | + * the exception. This function can be overridden in derived classes to provide more specific information about the |
| 9 | + * exception. |
| 10 | + * |
| 11 | + * `std::bad_alloc`, `std::runtime_error` and `std::invalid_argument` |
| 12 | + * |
| 13 | + * @version 0.1 |
| 14 | + * @date 2026-04-04 |
| 15 | + * |
| 16 | + * @copyright Copyright (c) 2026 |
| 17 | + * |
| 18 | + */ |
| 19 | + |
| 20 | +#include <iostream> |
| 21 | +#include <stdexcept> // for std::runtime_error and std::invalid_argument |
| 22 | +#include <string> |
| 23 | + |
| 24 | +class invalid_sensor_data_error_t : public std::runtime_error { |
| 25 | +public: |
| 26 | + explicit invalid_sensor_data_error_t(const std::string& message) |
| 27 | + : std::runtime_error(message) {} |
| 28 | +}; |
| 29 | + |
| 30 | +class sensor_processor_t { |
| 31 | +public: |
| 32 | + double process_reading(double value) const { |
| 33 | + if (value < 0.0) { |
| 34 | + throw invalid_sensor_data_error_t("Negative sensor value detected"); |
| 35 | + } else if (value > 1000.0) { |
| 36 | + throw invalid_sensor_data_error_t("Sensor value exceeds safe threshold"); |
| 37 | + } |
| 38 | + // Simulated processing |
| 39 | + return value * 0.5; |
| 40 | + } |
| 41 | +}; |
| 42 | + |
| 43 | +int main() { |
| 44 | + try { |
| 45 | + throw 500; // generates the exception |
| 46 | + } catch (int e) { // matches the catch block with the type of data (int) thrown |
| 47 | + std::cout << "An exception occurred. We saw exception: " << e << std::endl; |
| 48 | + } catch (char e) { |
| 49 | + std::cout << "char exception: " << e << std::endl; |
| 50 | + } catch (...) { |
| 51 | + // match any type of exception and is used to handle anything not caught by any of the other catch blocks |
| 52 | + std::cout << "default exception" << std::endl; |
| 53 | + } |
| 54 | + // After an exception is handled, execution resumes after the try-catch block, |
| 55 | + // and the program continues as normal. |
| 56 | + std::cout << "Program continues after handling the exception." << std::endl; |
| 57 | + |
| 58 | + try { |
| 59 | + throw std::runtime_error("Something bad happened"); |
| 60 | + } catch (const std::exception& e) { |
| 61 | + std::cout << "An exception occurred: " << e.what() << std::endl; |
| 62 | + } |
| 63 | + |
| 64 | + sensor_processor_t processor; |
| 65 | + |
| 66 | + constexpr double readings[] = {25.0, -5.0, 2000.0}; |
| 67 | + for (double value : readings) { |
| 68 | + try { |
| 69 | + double result = processor.process_reading(value); |
| 70 | + std::cout << "Processed value: " << result << std::endl; |
| 71 | + } catch (const invalid_sensor_data_error_t& e) { |
| 72 | + std::cerr << "Custom exception caught: " << e.what() << std::endl; |
| 73 | + } catch (const std::exception& e) { |
| 74 | + std::cerr << "Standard exception caught: " << e.what() << std::endl; |
| 75 | + } |
| 76 | + } |
| 77 | + |
| 78 | + return 0; |
| 79 | +} |
0 commit comments