引子:类型转换
1)普通类型之间的转换:static_cast 凡是可以隐式转换的地方都可以用,在编译时进行类型识别
a = ststic_cast<int>(d);
2)指针之间的转换:reinterpret_cast 可用来在指针和整型之间转换
p = reinterpret_cast<int *>(pd);
3)层次间转换:dynamic_cast 在运行时进行类型识别,基类和派生类之间转换;类型匹配则成功,不不匹配则失败,返回NULL指针;
Dog * p = dynamic_cast<Dog*>(p);
4)去掉只读属性:const_cast 只是去掉只读属性赋给前面的值,但其本身并无变化
char* p = const_cast <char*>(str);
1、异常处理
异常是一种程序控制机制,与函数机制独立和互补。可以用来改变程序的控制结构,但在错误处理方面取得了巨大好处。
1)使用throw可以抛出异常,然后可以使用try{}catch{}语句块来捕获并处理异常。
1、把可能发生异常的代码放在try(try不是处理错误,而是处理异常)中,异常需要人为抛出。2、异常是跨函数的
3、异常在捕获后:处理,不让其继续抛或者不处理,用throw继续往后抛4、catch捕获后,要严格遵循类型匹配,不允许任何形式的类型转换
2)从try开始到throw期间,在栈上创建的所有对象,当异常抛出的时候会被全部释放。析构顺序与构造顺序相反,成为栈解旋。但是堆上的对象需要自己处理,不会自动释放的3)异常接口声明:默认函数可以抛出任意类型的异常,但也可以限制抛出类型:
void fun()throw(A,B,C); // 该函数只能抛出ABC类型的异常
void fun() throw(); // 该函数不能抛出任何类型的异常
4)异常变量的生命周期:
当抛出一个对象时,
1、拿一个普通变量去收,会有匿名对象产生,但它的生命周期会直到异常处理完毕。
2、当拿引用去接这个匿名对象时,不会产生多个备份。
3、去接对象指针时,若在栈上,在异常接收前就释放了,接到的指针不可使用,它是非法指针。
4、去接一个堆上的对象指针,该对象不会自动释放,需要手动调用delete去释放
catch的类型:引用和普通变量不能共存,但引用和指针可以共存
5)异常在类层次中使用:用这样一个数组类来举例:对数组初始化时对数组的个数进行有效检查。这样的类除了需要一般的构造函数,析构函数等之外,在需要几个相关错误的处理类,让它们都继承自eSize类(内部类),这样,在构造函数中根据条件抛出这些错误处理类。在main函数中用try语句建数组类并用多态的知识利用基类的引用接错误类。
6)C++标准提供了一组标准异常类,这些类以基类Exception开始,标准程序库中抛出的所有异常,都派生于该基类,这些类的派生都继承了一个成员函数what(),用于返回错误信息(返回类型是const char*),声明如下:
virtual const char * what() const throw();
2、C++输入输出流
1)输入输出流:
标准设备:键盘,屏幕==>标准I/O
文件:读(in)写(out)文件==>文件I/O
内存:缓冲区、数组==>串I/O
2)
输入流:
3)文件操作ch = cin.get(); cin.get(ch); //getchar() cin.getline(str,100); //fgets (cin读不了空格) cin.ignore(3); //忽略3个字节往后读 ch = cin.peek(); //偷窥一个字节,并不撩 cin.putchar(ch); //吃完吐回到缓存区
1、读出
2、写入:类似读出ofstream f("test"); // 定义一个文件输出流对象,对象创建成功则已打开 f << "hello world" << endl; // 把f当cout用
3、关闭:f.close();
/* 案例:设计一个数组类 MyArray,重载[]操作, 数组初始化时,对数组的个数进行有效检查 1)index<0 抛出异常eNegative 2)index = 0 抛出异常 eZero 3)index>1000抛出异常eTooBig 4)eSize类是以上类的父类,实现有参数构造、并定义virtual void printErr()输出错误。 */
#include <iostream> using namespace std; class MyArray { public: MyArray(int len) { if (len < 0) { throw eNegative(len); } if (len == 0) { throw eZero(len); } if (len > 1000) { throw eTooBig(len); } this->len = len; m_p = new int[len]; } ~MyArray() { if (m_p != NULL) { delete []m_p; m_p = NULL; } len = 0; } int &operator[](int index) { return m_p[index]; } class eSize { public: eSize(int size) { this->size = size; } virtual void printErr() = 0; protected: int size; }; class eNegative { public: eNegative(int size) { this->size = size; } void printErr() { printf("result < 0\n"); } protected: int size; }; class eZero { public: eZero(int size) { this->size = size; } void printErr() { printf("result = 0\n"); } protected: int size; }; class eTooBig { public: eTooBig(int size) { this->size = size; } void printErr() { printf("result > 1000\n"); } protected: int size; }; protected: int len; int *m_p; }; int main() { try { MyArray a(3); for (int i = 0; i < 10; i++) { a[i] = i; } } catch(MyArray::eSize & e) // 多态 { e.printErr(); } catch(...) { printf("others\n"); } return 0; }