C++中的异常处理与模板类

一、C++ 中的异常处理

1、异常处理

在C++ 中可以抛出任何类型的异常,根据抛出的异常数据类型,进入到相应的 catch块中 ,未知类型可用 … 代替

void main() {
    try {
        int a = 300;
        if (a > 200) {
            throw - 1;
        }
    }
    catch (int a) {
        cout << a << endl;
    }
    try {
        int b = 0;
        if (b == 0) {
            throw "不能为0";
        }
    }
    catch (const char* b) {
        cout << b << endl;
    }

    try {
        int c = -1;
        if (c < 0 ) {
            throw 0.1;
        }
    }
    catch (...) {
        cout << "未知异常" << endl;
    }
    getchar();
}

2、throw 抛出函数外

float div2(float a, float b) {
    if (b == 0) {
        throw "除数为零";
    }
    return a / b;
}

void main() {
    try {
        float c = div2(8, 0);
    }
    catch (const char* e) {
        cout << e << endl;
    }

    getchar();
}

3、抛出异常对象

抛出异常对象可以使用异常对象来捕获异常或者使用异常对象的引用来捕获异常,采用引用方式不会产生副本(可实现拷贝构造函数来验证);尽量不要抛出异常指针(new 动态内存),需要delete动态内存

//异常类
class MyException {
public:
    MyException() {

    }
};

float div2(float a, float b) {
    if (b == 0) {
        //抛出对象
        throw MyException();
        //抛出异常指针
        throw new MyException;
    }
    return a / b;
}

void main() {
    try {
        float c = div2(8, 0);
    }
    //catch (MyException e) {//对象,被拷贝了对象,产生对象副本
    //    cout << "MyException" << endl;
    //}
    catch (MyException &e1) {//对象的引用,效率更高
        cout << "MyException引用" << endl;
    }
    //catch (MyException* e2) {//异常指针,需要delete
    //    cout << "MyException指针" << endl;
    //    delete e2;
    //}


    getchar();
}

4、声明抛出异常的类型

throw 加载函数名称上,表示声明函数会抛出的异常类型

float div2(float a, float b) throw(char*,int) {
    if (b == 0) {
        throw "除数为零";
    }
    return a / b;
}

void main() {
    try {
        float c = div2(8, 0);
    }
    catch (const char* e) {
        cout << e << endl;
    }
    getchar();
}

5、标准异常(类似于Java NullPointerException)

需要引入

#define <stdexcept> 
class NullPointerException : public exception{
public:
    NullPointerException(char* msg) : exception(msg){

    }
};

float div2(float a, float b) throw(char*,int) {
    if(b == NULL){
        throw NullPointerException("is NULL");
    } else if (b > 10000) {
        throw out_of_range("超出范围");
    }else if(b == 0){
        throw invalid_argument("参数不合法");
    }
    return a / b;
}

void main() {
    try {
        float c = div2(8, 0);
    }
    catch (out_of_range e) {
        cout << e.what() << endl;
    }
    catch (NullPointerException& e1) {
        cout << e1.what() << endl;
    }
    catch (...) {
        cout << "未知异常" << endl;
    }
    getchar();
}

二、模板类

属性或者构造函数中存在泛型参数的类叫模板类

1、模板类示例

template<class T>
class A{
public:
    A(T a){
        this->a = a;
    }
protected:
    T a;
};

2、普通类继承模板类

class B : public A<int>{
public:
    B(int a,int b) : A<int>(a){
        this->b = b;
    } 
private:
    int b;
}

3、模板类继承模板类

template<class T>
class C : public A<T>{
public:
    C(T a,T c) : A<T>(a){
        this->c = c;
    } 
protected:
    T c;
}

4、模板类对象实例化

void main(){
    //实例化模板类对象
    A<int>(6);
    getchar();
}