C++ exception mechanism (on)

C++ exception mechanism (below)

1. Concept

Abnormal: Abnormal behaviors that exist at runtime. These behaviors exceed the normal functional scope of the function.

Exception handling: To handle errors in the program, the exception handling mechanism provides support for the cooperation of the two parts of the program, exception detection and exception handling.

In C++, exception handling includes:

  • Throw expression, indicating that a problem that cannot be handled has been encountered
  • try block, handle exceptions; start with the keyword try and end with one or more catch
  • A set of exception classes used to transfer exception information between throw expressions and related catch clauses.

2. Abnormal benefits

  1. The integral return value has no semantic information, and the exception contains semantic information, which can sometimes be seen from the class name.
  2. As a class, an exception has its own members and can convey enough information.
  3. The return value of the function can be ignored, the exception can not be ignored, can make the program more robust.

3. Basic grammar

#include<iostream>
using namespace std;

//异常基本语法

int divide(int x ,int y){
    
    
	if (y == 0){
    
    
		throw y;  //抛异常
	}
	return x / y;
}
void test01(){
    
    

	//试着去捕获异常
	try{
    
    
		divide(10, 0);
	}
	catch (int e){
    
     //异常时根据类型进行匹配
		cout << "除数为" << e << "!" << endl;
	}	
}


void CallDivide(int x,int y){
    
    	
	divide(x, y);
}
//a() -> b() - >c()  -> d(),d()中的异常一层层向上抛到terminate的标准库函数,直到处理为止

void test02(){
    
    	
	try{
    
    
		CallDivide(10,0);
	}
	catch (int e){
    
    
		cout << "除数为" << e << endl;
	}
}

//C++异常机制跨函数
//异常必须处理,如果异常抛到顶层还没有处理,程序便会挂掉。
int main(){
    
    
	
	//test01();
	test02();
}

Four, stack unspin

After the exception is thrown, from entering the try block to before the exception is thrown, all objects constructed on the stack during this period will be automatically destroyed. The order of destruction is opposite to the order of construction. This process is called the stack. Untwist .

The constructor has no return type and cannot report the running status through the return value, so the error mechanism of the constructor is solved through the exception mechanism.

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

class Person{
    
    
public:
	Person(){
    
    
		cout << "对象构建!" << endl;
	}
	~Person(){
    
    
		cout << "对象析构!" << endl;
	}
};

int divide(int x,int y){
    
    
	Person p1, p2;
	if (y == 0){
    
    
		throw y;
	}
	return  x / y;
}

void test01(){
    
    

	try{
    
    
		divide(10,0);//栈解旋
	}
	catch (int e){
    
    
		cout << "异常捕获!" << endl;
	}
}

int main(void)
{
    
    
	test01();
	return 0;
}
/*
结果:
    对象构建!
	对象构建!
	对象析构!
	对象析构!
	异常捕获!
*/

Five, abnormal interface statement

  1. In order to enhance the readability of the program, you can list all the exception types that may be thrown in the function declaration, for example:
    void func() throw (A, B, C, D); //This function func() can and only Can throw exceptions of type ABCD and its subtypes.
  2. If the function declaration does not include the exception interface declaration, the sub-function can throw any type of exception, for example:
    void func();
  3. A function that does not throw any type of exception can be declared as:
    void func() throw();
  4. If a function throws an exception that is not allowed by its exception interface declaration, the unexpected function will be called. The default behavior of the function is to call the terminate function to terminate the program.
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

//这个函数只能抛出int float char三种类型异常,抛出其他的就报错
void func() throw(int,float,char){
    
    
	throw "abc";
}

//不能抛出任何异常
void func02() throw(){
    
    
	throw -1;
}

//可以抛出任何类型异常
void func03(){
    
    
}

int main(void)
{
    
    
	try{
    
    
		func();
	}
	catch (char* str){
    
    
		cout << str << endl;
	}
	catch (int e){
    
    
		cout << "异常!" << endl;
	}
	catch (...){
    
     //捕获所有异常
		cout << "未知类型异常!" << endl;
	}
	return 0;
}

//结果: 未知类型异常!

Six, the memory model of abnormal objects

The exception thrown has a type, which can be a number, a string, or a class object. The catch must strictly match the exception type.

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

void func01(){
    
    
	throw 1; //抛出int类型异常
}

void func02(){
    
    
	throw "exception";
}

class MyException{
    
    
public:
	MyException(const char* str){
    
    
		error = new char[strlen(str)+1];
		strcpy(error, str);
	}
	
	MyException(const MyException& ex){
    
    
		this->error = new char[strlen(ex.error) + 1];
		strcpy(this->error,ex.error);
	}
	MyException& operator=(const MyException& ex){
    
    
		if (this->error != NULL){
    
    
			delete[] this->error;
			this->error = NULL;
		}
		this->error = new char[strlen(ex.error) + 1];
		strcpy(this->error, ex.error);
	}
	
	void what(){
    
    
		cout << error << endl;
	}
	~MyException(){
    
    
		if (error != NULL){
    
    
			delete[] error;
		}
	}
public:
	char* error;
};

void fun03(){
    
    
	throw MyException("我刚写异常!");
}

void test01(){
    
    	
	try{
    
    
		func01();
	}
	catch (int e){
    
    
		cout << "int 异常捕获!" << endl;
	}
//----------------------------------
	try{
    
    
		func02();
	}
	catch (const char* e){
    
    
		cout << "const char* 异常捕获!" << endl;
	}
//----------------------------------
	try{
    
    
		fun03();
	}
	catch (MyException e){
    
    
		e.what();
	}
}
int main(void){
    
    	
	test01();
	return 0;
}
/*
int 异常捕获!
const char* 异常捕获!
我刚写异常!
*/

Seven, the life cycle of abnormal objects

  1. Common type elements, references, and pointers can be used in catch
  2. Common elements are picked up, and the exception object is destructed after the catch is processed
  3. For reference, there is no need to call the copy construction, the exception object is destructed after the catch is processed
  4. Pointer connection, when throwing, you must use new to connect, and you must delete in catch
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

class MyException {
    
    
public:
	MyException() {
    
    
		cout << "构造函数!" << endl;
	}
	MyException(const MyException& ex) {
    
    
		cout << "拷贝构造!" << endl;
	}
	~MyException() {
    
    
		cout << "析构函数!" << endl;
	}
};
void func() {
    
    
	//throw &(MyException()); //创建匿名对象,调用构造
    //throw new MyException();//用指针接
	throw MyException();
}
void test01();
int main(void) {
    
    
	test01();
	return 0;
}

/*
void test01();{
	try {
		func();
	}
	catch (MyException e) {
		cout << "异常捕获!" << endl;
	}
}
普通类型去接,结果为:
	构造函数!
	拷贝构造!
	异常捕获!
	析构函数!
	析构函数!
*/

/*
void test01();{
	try {
		func();
	}
	catch (MyException& e) {
		cout << "异常捕获!" << endl;
	}
}
引用去接,结果为:
	构造函数!
	异常捕获!
	析构函数!
*/
/*
void test01();{
	try {
		func();
	}
	catch (MyException* e) {
		cout << "异常捕获!" << endl;
		detele e;
	}
}
指针去接,结果为:
	构造函数!
	异常捕获!
	析构函数!
*/

Guess you like

Origin blog.csdn.net/weixin_45341339/article/details/112719175