// excepciones.cpp - Tratamiento de excepciones
#include <limits>
#include <string>
#include <iostream>
using namespace std;

class EValorNoValido
{
    string mensajeDeError;
  public:
    EValorNoValido(string mensaje = "valor no válido")
    {
      mensajeDeError = mensaje;
    }
    string what() { return mensajeDeError; }
  // ...
};

double leerDouble()
{
  cin.exceptions(ios::failbit | ios::badbit);
  double dato = 0.0;
  try
  {
    cin >> dato;
  }
  catch(ios_base::failure& e)
  {
    cout << e.what() << ": dato no válido\n";
    cin.clear();
    cin.ignore(numeric_limits<int>::max(), '\n');
  }
  return dato; // devolver el dato tecleado
}

void f(double) throw(EValorNoValido, bad_exception);

int main()
{
  double d = 0;
  cout << "dato: "; d = leerDouble();
  // ...
  cout << d << endl;
  
  try
  {
    f(d);
  }
  catch(EValorNoValido& e)
  {
    cout << e.what() << endl;
  }
  catch(bad_exception& e)
  {
    cout << "error: " << e.what() << endl;
  }
  
  system("pause");
}

void excepcion_inesperada()
{
  throw std::bad_exception();
}

void f(double a) throw(EValorNoValido, bad_exception)
{
  set_unexpected(excepcion_inesperada);
  if (a == 0)
    throw EValorNoValido("Error: valor cero");
  // ...
  // Supongamos que en este punto ocurre una excepción inesperada
  throw "excepción inesperada";
  // ...
}

