Day 11 C + + exception handling

Posted by rami103 on Sat, 29 Jan 2022 23:53:26 +0100

1, Basic exception handling

  • Exception handling mechanism: suspend the problem handling, not in the current function, but in other callers (for example, function 1 calls function 2, and function 2 also calls function 3. If an exception is throw n in function n, we can handle it in any of the previous functions.)

  • What is an exception? Anything can be regarded as an exception. Error is only one kind of exception

  • Once an exception is thrown, it will not be handled. If an exception is thrown, the default abort termination program will be called

  • Catch and handle exceptions

    • throw throws an exception (it can be understood as a return value, which can be of any type, so that we can handle the exception as a reference)

    • Try (check, catch) and catch (handle exceptions) (Note: if there are normal statements after catch, it will continue.)

      //try and catch must appear together, and they {} cannot be omitted
      try
      {
      	//If it is normal, you need to check whether there is an exception code   
      }
      catch(type)     //Understood as case statement in switch
      {
          //Processing is to decide how to process according to the thrown data type
      }
      //A try can correspond to multiple catch es
      try
      {
      	//...    
      }
      catch(int)
      {
      	    
      }
      catch(double)
      {
          
      }
      catch(string)
      {
      	    
      }
      //catch and if else_ The if execution mechanism is the same, and only one match can be executed

      //Prune Any type of exception is caught

catch(...)

No exception description / / written after the function

  • throw ()

  • noexcept

    void  print() throw() 
    {
    	cout << "There is no exception throwing operation in the current function" << endl;
    }
    void printData() noexcept 
    {
    	cout << "New description: no exception thrown" << endl;
    	//throw 0;   However, once it is stated that there is no abnormal operation, it cannot be thrown
    }

    2, Parameter transfer in exception handling

  • catch(int a) / / hide a parameter passing operation

  • To handle the exception handling of throwing strings, pay attention to the difference between string type and const char * type

  • You can also throw objects of your own class

    #include <iostream>
    #include <string>
    using namespace std;
    class Error 
    {
    public:
    	Error(const char* str = "unknown error") :str(str) {}
    	const char* what()const 
    	{
    		return str.c_str();
    	}
    protected:
    	string str;
    };
    int divisor(int a, int b) 
    {
    	if (b == 0)
    		throw "Divisor cannot be 0";
    	if(b==1)
    		throw "Divisor cannot be 1";
    	if(b==2)
    		throw string("Divisor cannot be 2");
    	return a / b;
    }
    void insertArray(int array[], int* curNum, int posData,int maxLength) 
    {
    	if (*curNum >= maxLength)  //3>=3
    	{
    		throw  Error("Array index overflow!");
    	}
    	//0 1 2
    	array[*curNum] = posData;  //array[3]=3
    	(*curNum)++;
    }
    
    int main()
    {
    	try
    	{
    		divisor(1, 0);
    	}
    	catch (const char* str)  //str= 	 "Divisor cannot be zero";
    	{
    		cout << str << endl;
    	}
    	try
    	{
    		divisor(1, 2);
    	}
    	catch (string str)
    	{
    		cout << str << endl;
    	}
    	try
    	{
    		int array[3] = { 0,0,0 };
    		int curNum = 0;
    		for (int i = 0; i < 4; i++) 
    		{
    			insertArray(array, &curNum, i, 3);
    		}
    	}
    	catch (Error str) //catch is used to pass parameters.
    	{
    		cout << str.what() << endl;
    	}
    
    	return 0;
    }

    3, Exceptions in the standard library

  • exception is the base class, and the rest are its derived classes

< exception > has a what() method. Usage example: (in try, the system will automatically pop up a bad_alloc object)

bad_typeid,bad_cast,bad_alloc,ios_base::failure,out_of_range is derived from the exception class. When C + + program encounters some exceptions, even if the throw statement is not written in the program, it will automatically throw the object of the above exception class. These exception classes also have member functions called what, which return exception description information in string form. To use these exception classes, you need to include the header file stdecept or exception. (header file)

#include <exception>
int main()
{
	try
	{
		while (1)
		{
			int* p = new int[1024 * 1024 * 10];
		}
	}
	catch (bad_alloc& object)
	{
		cout << object.what() << endl;
	}
	return 0;
}

Write an exception to restore the code in the standard library:

class Exception
{
public:
	Exception(const char* ptr = "UNKNOW") :ptr(const_cast<char*>(ptr)) {}
	virtual const char* what() const
	{
		return ptr;
	}
protected:
	char* ptr;
};
class Bad_alloc :public Exception
{
public:
	Bad_alloc(const char* _Message = "bad exception") :Exception(_Message) {}
protected:
};
class Run_time :public Exception
{
public:
	Run_time(const char* _Message = "run_time error") :Exception(_Message) {}
protected:
};

Note: for inherited subclasses, the properties of the parent class should use the constructor of the parent class. Then the subclass assigns a value to Exception and calls the what method in Exception (if Exception is not initialized, the return in what is the default unknown string constant)

The process is similar to the following code:

class A
{
public:
	A(int num):num(num){}
	int returna()
	{
		return num * 10;
	}
protected:
	int num;
};
class B:public A
{
public:
	B(int num,int b):A(num),b(b){}
protected:
	int b;
};
int main()
{
	B b(10, 11);
	cout << b.returna() << endl;
	return 0;
}

Output: 100

4, Exception of custom class

(write a class or derived class for multiple error situations)

① Write your own exception class Error

class Error
{
public:
	Error(const char* str):str(const_cast<char*>(str)){}
	const char* what()const
	{
		return str;
	}
protected:
	char* str;
};
int divide(int a, int b)
{
	if (b == 0)
		throw Error("Denominator cannot be 0");
	return (a / b);
}
void testError()
{
	try
	{
		int result = divide(112, 0);
	}
	catch (Error&p)
	{
		cout << p.what() << endl;
	}
}

② Inherit the exception class in the standard library by overriding the what method: class MyException

//Inherit the exception class in the standard library by overriding the what method: class MyException
class MyException :public exception
{
public:
	MyException(string str) :exception(str.c_str()) {};
};
void insertArray(int cap)
{
	if (cap >= 5)
		throw MyException("The array is full");
	cout << "Insert successful" << endl;
}
void testMyException()
{
	try
	{
		insertArray(6);
	}
	catch (MyException& d)
	{
		cout << d.what() << endl;
	}
}

Topics: C++ Back-end