Click on exception.cpp to get source.
// File: exception.cpp
//       compile as g++ -Wall -ansi -std=c++23 exception.cpp

#include <iostream>
#include <stdexcept>
#include <cmath>

using namespace std;

// class header info
class Integer
  {int x;
   public:
   Integer() : x(0) {}
   Integer(const int i) : x(i) {}
   inline Integer operator/(const Integer j)
      // throw(std::invalid_argument) // indicate what the func may throw
                         // this is not necessary but helps the caller
   ;                    
   friend ostream& operator<<(ostream& os, const Integer& i);
  };// class Integer

// implementation
inline Integer Integer::operator/(const Integer j)
      // throw(std::invalid_argument)
      {if(j.x == 0)
         throw(std::invalid_argument(
                 "in Integer::operator/: division by zero")
              );
       else return this->x/j.x;
      }//Integer::operator/

ostream& operator<<(ostream& os, const Integer& i)
  {os << i.x; return os; }//operator<<

int main(void)
{int x=3, y;
 double frac_x_y;

 cout << "Catching int zero divisions by std::isinf()" << endl;
 for(y=3; y>=0; y--)
    {cout << "x=" << x << ", y=" << y << endl;
     frac_x_y = static_cast<double>(x)/static_cast<double>(y);
     if(std::isinf(frac_x_y)) cout << "division by zero" << endl;
     else cout << "static_cast<int>(double)=" << static_cast<int>(frac_x_y)
               << ", x/y=" << x/y << endl;
    }//for
 cout << endl;

 cout << "Catching int zero divisions by throwing exception in user defined class" << endl;
 try
 { Integer three = 3; Integer two = 2; Integer zero = 0;
   cout << "three/two=" << three/two << endl;
   cout << "trhee/zero=" << three/zero << endl;
 }//try
 catch (std::invalid_argument& m)
     { cout << endl << "Exception: " << m.what() << endl;
     }//catch

}//main