← Back to C++ Course | Chapter 12: Exception Handling | Lesson 5 of 5

C++ Exception Hierarchy

C++'s standard exceptions are organized in a family tree, with general problems as parents and specific ones as children. Knowing it helps you catch the right kind.
Syntax
cpp
#include <stdexcept>

try {
  throw std::runtime_error("message");
} catch (const std::exception &e) {
  e.what();
}

Overview of Standard Exceptions

C++'s standard exceptions form a hierarchy rooted at std::exception, which branches into two broad categories: std::runtime_error for problems caused by unpredictable external factors, and std::logic_error for bugs that a careful programmer could have prevented ahead of time.

Example: Overview of Standard Exceptions

cpp
// Include std::cout and std::cin
#include <iostream>
#include <stdexcept>

// Program execution starts in main()
int main() {
	// Try code that might throw an exception
	try {
		// Throw an exception to signal an error
		throw std::runtime_error("Runtime issue");
	// Handle the exception if one was thrown
	} catch (std::exception &e) {
		// Print to the console with cout
		std::cout << e.what() << std::endl;
	}
	// Return 0 to signal that the program finished successfully
	return 0;
}

Runtime Errors (runtime_error)

A runtime_error represents a failure that logic checks alone can't reliably predict in advance — things like a network timeout, a hardware fault, or a full disk, which depend on conditions outside the program's own control.

Example: Runtime Errors (runtime_error)

cpp
// Include std::cout and std::cin
#include <iostream>
#include <stdexcept>

// Program execution starts in main()
int main() {
	// Try code that might throw an exception
	try {
		// Throw an exception to signal an error
		throw std::runtime_error("Network timeout");
	// Handle the exception if one was thrown
	} catch (std::runtime_error &e) {
		// Print to the console with cout
		std::cout << e.what() << std::endl;
	}
	// Return 0 to signal that the program finished successfully
	return 0;
}

Logic Errors (logic_error)

A logic_error, by contrast, represents a mistake that was theoretically avoidable through correct code — passing an invalid argument, or trying to access a container element that's out of range, are both classic examples of preventable logic errors.

Example: Logic Errors (logic_error)

cpp
// Include std::cout and std::cin
#include <iostream>
#include <stdexcept>

// Program execution starts in main()
int main() {
	// Try code that might throw an exception
	try {
		// Throw an exception to signal an error
		throw std::invalid_argument("Invalid argument passed");
	// Handle the exception if one was thrown
	} catch (std::logic_error &e) {
		// Print to the console with cout
		std::cout << e.what() << std::endl;
	}
	// Return 0 to signal that the program finished successfully
	return 0;
}

Catching by Base Reference

You should always catch exceptions by const reference rather than by value, because catching by reference preserves the object's real polymorphic type and avoids object slicing, which would otherwise cut a derived exception down to just its base class portion.

Example: Catching by Base Reference

cpp
// Include std::cout and std::cin
#include <iostream>
#include <stdexcept>

// Program execution starts in main()
int main() {
	// Try code that might throw an exception
	try {
		// Throw an exception to signal an error
		throw std::out_of_range("Index out of range");
	// Handle the exception if one was thrown
	} catch (const std::exception &e) {
		// Print to the console with cout
		std::cout << e.what() << std::endl;
	}
	// Return 0 to signal that the program finished successfully
	return 0;
}

Bad Allocations (bad_alloc)

std::bad_alloc is thrown directly by the standard library's memory allocator — most commonly triggered by the new operator — whenever the system genuinely runs out of free heap memory and an allocation request simply cannot be satisfied.

Example: Bad Allocations (bad_alloc)

cpp
// Include std::cout and std::cin
#include <iostream>
#include <new>

// Program execution starts in main()
int main() {
	// Try code that might throw an exception
	try {
		// Throw an exception to signal an error
		throw std::bad_alloc();
	// Handle the exception if one was thrown
	} catch (std::bad_alloc &e) {
		// Print to the console with cout
		std::cout << e.what() << std::endl;
	}
	// Return 0 to signal that the program finished successfully
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Catching a base exception before a derived one, so the derived handler never runs.
  2. Catching by value instead of by reference, which slices the exception.
  3. Forgetting #include <stdexcept> before using runtime_error or logic_error.
Chapter Summary
  • Exception handling deals with runtime errors without crashing the program.
  • try, catch, and throw signal and handle exceptions.
  • Custom exceptions and an exception hierarchy let you create meaningful error types.
🔒

Chapter Quiz — Complete all 5 topics to unlock

0/5 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.