目录
就是将一种数据类型转换成另一种数据类型。例如,如果将一个整型值赋给一个浮点类型的变量,编译器会暗地里将其转换成浮点类型。
标准C++提供了一个显式的转换语法,来替代C风格的类型转换。
C++风格的强制转换可以更好地控制转换过程。
(1)用于基本数据类型之间的转换。
- void test()
- {
- char a = 'a';
- double b = static_cast<double>(a);
- }
(2)用于类层次结构中父类和子类之间指针或引用的转换。
父类转子类是不安全的;子类转父类是安全的。
主要用于类层次间的上行转换和下行转换;
基础类型不能使用动态转换;
向上转时,dynamic_cast 和 static_cast 的效果是一样的;
向下转时,dynamic_cast 具有类型检查的功能,比static_cast更安全;
用来修改类型的 const 属性;
常量指针被转换成非常量指针,仍然指向原来的对象;
常量引用被转换成非常量引用,仍然指向原来的对象;
不能直接对非指针和非引用的变量使用const_cast操作符去直接移除它的const。
- void test()
- {
- const int* p = NULL;
- //const -> 非const
- int* newP = const_cast<int*>(p);
- //非const -> const
- int* q = NULL;
- const int* newQ = const_cast<const int*>(q);
- }
最不安全的转换。
主要用于将一种数据类型从一种类型转换为另一种类型。
可以将一个指针转换成一个整数,也可以将一个整数转换成一个指针。
- void test()
- {
- //int转换成指针
- int a = 1;
- int* p = reinterpret_cast<int *>(a);
- //也可以对没有继承关系的类之间进行转换
- Father* f = NULL;
- Other* o = reinterpret_cast
(f); - }
异常处理就是处理程序中的错误。所谓错误是指在程序运行过程中发生的一些异常事件(如:除0溢出、数组下标越界、所要读取的文件不存在、空指针、内存不足等)。
① 使用整型的返回值标识错误;② 使用 error 宏去记录错误。
缺陷:
C++的异常处理可以解决这些问题。
C++的异常处理使得异常的引发和处理不必在一个函数中,这样底层的函数可以着重解决具体问题,而不必过多的考虑异常的处理。上层调用者可以在适当的位置设计对不同类型异常的处理。
- int func(int a, int b)
- {
- if (b == 0)
- {
- throw 10; //抛出int类型的异常
- throw 'a'; //抛出char类型的异常
- throw "hello"; //抛出char*类型的异常
- string str="hahaha";
- throw str;
- }
- return a / b;
- }
- void test()
- {
- int a = 10;
- int b = 0;
- try
- {
- func(a, b);
- }
- catch (int)
- {
- cout << "接收一个int类型的异常" << endl;
- }
- catch (char)
- {
- cout << "接收一个char类型的异常" << endl;
- }
- catch (char*)
- {
- cout << "接收一个char*类型的异常" << endl;
- }
- catch (...)
- {
- cout << "接收其他类型的异常" << endl;
- }
- }
- void func() throw(int, char) //只允许抛出 int 或者 char 异常
- {
- throw 10;
- }
运行结果如下,可以看出,进行了两次构造,只进行了一次析构,所以发生了栈解旋。
- Maker构造
- Maker拷贝构造
- Maker析构
- 接收一个Maker异常
- Maker析构
使用上边的 Maker 类。
- //异常的基类
- class Father
- {
- public:
- virtual void printM()
- {}
- };
- //1.有继承
- class SonNULL :public Father
- {
- public:
- virtual void printM() //2.重写父类的虚函数
- {
- cout << "空指针异常" << endl;
- }
- };
- class SonOut :public Father
- {
- public:
- virtual void printM()
- {
- cout << "越位溢出" << endl;
- }
- };
-
-
- void func(int a, int b)
- {
- if (a == 0)
- {
- throw SonNULL();
- }
- if (b == 0)
- {
- throw SonOut();
- }
- }
-
- void test()
- {
- int a = 0;
- int b = 1;
- try
- {
- func(a,b);
- }
- catch(Father& f) //3.父类引用指向子类对象
- {
- f.printM();
- }
- }
- class Myout_of_range :public exception
- {
- public:
- Myout_of_range (const char* errinfo)
- {
- //const char*转换为string
- this->m_info = string(errinfo);
- }
- Myout_of_range (const string errinfo)
- {
- this->m_info = errinfo;
- }
- const char* what() const
- {
- //把string转换成const char*
- return this->m_info.c_str();
- }
- public:
- string m_info;
- };
-
- class Maker
- {
- public:
- Maker(int age)
- {
- if (age < 0)
- {
- throw Myout_of_range ("自己的异常类,age is not correct");
- }
- else
- {
- this->age = age;
- }
- }
- public:
- int age;
- };
-
- void test()
- {
- try
- {
- Maker m(-1);
- }
- catch(Myout_of_range& my)
- {
- cout << my.what() << endl;
- }
- }