A bug is a failure in the design or execution of your code. An exception, on the other hand, is a predictable event, which you must handle, but which is outside the normal flow of execution. For example, if your code is supposed to add two numbers, but instead divides them, that is a bug. If your code is supposed to write a file to disk but the disk is full, that is an exception.
Running a class member function is a process of executing the machine instructions defined by the compiled version of the member function. These steps represent an attempt to fulfill the contract that defines the member function. At times, it makes no sense to complete this processing.
Member functions are supposed to complete their work and return a value. It may be impossible to tell the caller that the function has failed and that the returned values are meaningless. Even if there is a way to return this status, it can be very cumbersome to check these return values throughout the code. Exceptions provide a mechanism to follow the thread of execution, and yet handle problems as they arise.
Before exception handling, C and C++ programmers had two choices. They could miss some errors, or they could build solid robust code that checked the return value of every function call and handled errors appropriately. Unfortunately, this good code was so encrusted in error handling routines that it became difficult to find the main line of execution. Such code is difficult to write, debug, understand and maintain.
C++ now provides native exceptions. The contract the compiler offers is this: if you call a function, you will either get back a meaningful result or the system will throw an exception.
Exceptions are classes, and as such they can have both methods and data. Because exceptions are classes, you can delegate most of the work for understanding the error to the exception itself.