1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | 一、类模板 1、类模板:是一种使用了未知类型来设计类 template<typename M,typename T,typename R> class Test { M num; public: Test(M num) {} R func(T t) { R ret = t; return ret; } }; 2、类模板的使用 必须先实例化才能使用,与函数模板不同的是它不支持自动实例化,必须显示手动实例化 类名<类型参数> 对象名(初始化数据); 练习:实现链式的队列模板 3、类模板的静态成员 类模板的静态成员与普通类的静态成员一样,只在data\bss中存储一份,二期一样需要在类内声明、类外定义,但是定义时需要给参数类型,以及前面加template<> template<> 变量类型 类名<类型参数>::静态变量名 = 初始化数据; template<> int Test<char>::num = 1234; 4、类模板的递归实例化 什么类型都可以是模板的类型参数,包括类模板 类名1<类名2<类型> > 对象; // 一定要加空格 template<typename T> class A{ T b; }; template<typename T> class B{}; A<B<char> > a; 5、类模板的默认形参 类模板可以与函数模板一样设置默认形参,规则也一样 template<typename T1,typename T2=int> class Test { T1 val; public: Test(T2 val){} }; 6、类的局部特化 当类模板中的成员函数不能支持所有类型时,可以针对不同的类型实现类模板中成员函数的特化,这种叫做局部特化 方法1:在原成员函数中,通过tpyeid 比较是不是特殊类型,如果是可以通过分支语句进行特殊的处理 if(typeid(T) == typeid(const char*)) { if(0 == strcmp()) // 特殊处理 } else { if( == ) // 普通处理 } 7、类的全局特化 为一个特殊类型,整个类模板重新实现一个特化的类模板,这种叫做类的全局特化 template<> class 类名<特殊类型名> { 特殊类型 成员名; // 重新写整个类的内容 }; 8、在定义类模板和函数模板时,class关键字可以替换typename 二、C++的异常处理 1、什么是异常: 当代码出现错误,停止执行,返回一个数据 C语言中调用者只能立即使用返回值,或者使用变量接收返回值 C++可以根据返回值类类型的不同,从而执行不同的错误处理语句 2、如何抛出异常 throw 数据 任何类型数据都可以当做异常抛出,但是不要抛局部变量的地址或引用 3、如何捕获异常 try{ // 可能抛出异常的代码或函数调用 }catch(类型& 变量名){ // 抛出的异常会接收到该变量中 // 错误处理的代码 } 4、异常说明 返回值 函数名(参数列表)[异常说明] { } void func(void) throw(类型1,类型2,...) { } 异常说明:相当于该函数抛出异常的限制或者承诺,只能抛出说明过的异常类型,如果函数抛出了异常说明以外的异常类型,运行时会产生核心已转储的错误 5、标准异常 C++中已经定义好的异常类,当异常发生时,系统会自动抛出定义好的对应的标准异常类对象 std::exception 所有标准异常类的父类,能捕获所有的标准异常 std::bad_alloc new分配内存失败时抛出的异常 std::bad_cast dynamic_cast 类型转换失败抛出的异常 std::bad_exception 这在处理C++ 程序中无法预期的异常时非常有用。 std::bad_typeid 该异常可以通过typeid 抛出,当获取具有多台属性的类型指针时,typeid需要访问虚指针来确定实际的类对象是父类还是子类,如果类的指针非法,访问不到虚指针,从而抛出异常 6、自定义异常 class ZZError { string time; string file; string func; size_t line; string error; public: ZZError(const string& time,const string& file,const string& func,size_t line,const string& error):time(time),file(file),func(func),line(line),error(error) {} const string& what_error(void) { return error; } friend ostream& operator<<(ostream& os,const ZZError& e) { return os << "time:" << e.time << " file:" << e.file << " func:" << e.func << " line:" << e.line << " error:" << e.error; } }; |
类模板和异常处理
最新推荐文章于 2024-06-12 16:47:07 发布