- 七、转换函数
- 1、标准转换函数
- 例30、reinterpret_cast
- 例31、const_cast
- 例32、static_cast
- 例33、dynamic_cast
- 2、自定义转换函数
- 例34、operator
- 3、隐式构造
- 例35、explicit
//1. reinterpret_cast例30、reinterpret_cast(expression) 将一个类型的指针转换为另一个类型的指针,它也允许从一个指针转换为整数类型 //2. const_cast (expression) const 常量指针与普通指针间的相互转换 注:不能将非常量指针变量转换为普通变量 //3. static_cast (exprssion) 主要用于基本类型间的相互转换,和具有继承关系间的类型转换 //4. dynamic_cast (expression) 只有类中含有虚函数才能使用 dynamic_cast ,只能在继承类对象间转换 //1和2比较危险,后续可能会被淘汰,3和4在项目中偶尔还会遇到
首先回顾C语言的强制转换,错误案例如下
#include#include using namespace std; int main() { int a; char *p =&a; }
错误结果如下
@ubuntu:/mnt/hgfs/ub2$ g++ cast1.cpp
cast1.cpp: In function ‘int main()’:
cast1.cpp:11:12: error: cannot convert ‘int*’ to ‘char*’ in initialization
char *p =&a;
^
@ubuntu:/mnt/hgfs/ub2$
所以需要进行强制转换
#include#include using namespace std; int main() { int a; char *p =(char *)&a; }
以上是C语言的做法,在C++中,写成如下形式
#include例31、const_cast#include using namespace std; int main() { int a; char *p =reinterpret_cast (&a); }
同样的道理,在C语言中,对修饰为常量的参数取地址会出错,如下
#include#include using namespace std; int main() { const int b = 100; int *p = &b; }
@ubuntu:/mnt/hgfs/ub2$ g++ cast3.cpp
cast3.cpp: In function ‘int main()’:
cast3.cpp:10:14: error: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]
int *p = &b;
^~
@ubuntu:/mnt/hgfs/ub2$
在C++中,有方式实现把常量的地址强转为其它的数据类型
#include#include using namespace std; int main() { const int b = 100; int *p =const_cast (&b); }
注意,这种做法很危险,不推荐。
例32、static_cast然后接下来是静态方面的强制转换
#include#include using namespace std; class A{ }; class B:public A{ }; int main() { A a; B &p = a; }
运行结果报错
@ubuntu:/mnt/hgfs/ub2$ g++ cast5.cpp
cast5.cpp: In function ‘int main()’:
cast5.cpp:19:10: error: invalid initialization of reference of type ‘B&’ from expression of type ‘A’
B &p = a;
^
@ubuntu:/mnt/hgfs/ub2$
在C++中可以进行强制转换,写成
#include#include #include using namespace std; class A{ }; class B:public A{ }; int main() { A a; B &p = static_cast(a); }
这种做法跟const_cast 那样也是很危险,不推荐。
例33、dynamic_cast这时候可以使用高级一点的强制转换dynamic_cast
#include#include using namespace std; class A{ }; class B:public A{ }; int main() { A a; B &p = dynamic_cast( a ); }
这时候错误反馈信息就很到位
@ubuntu:/mnt/hgfs/ub2$ g++ cast7.cpp
cast7.cpp: In function ‘int main()’:
cast7.cpp:18:31: error: cannot dynamic_cast ‘a’ (of type ‘class A’) to type ‘class B&’ (source type is not polymorphic)
B &p = dynamic_cast( a );
^
@ubuntu:/mnt/hgfs/ub2$
当使用到虚函数时候,就变成了警告,编译也让过,但执行就会出问题,如下所示
#include#include #include using namespace std; class A{ public: virtual void show() { cout<<"aaaaaaa"< public: void show() { cout<<"bbbbbbbbbbbbaaaaaaa"< A a; B &p = dynamic_cast( a ); }
结果
@ubuntu:/mnt/hgfs/ub2$ g++ cast8.cpp
cast8.cpp: In function ‘int main()’:
cast8.cpp:27:31: warning: dynamic_cast of ‘A a’ to ‘class B&’ can never succeed
B &p = dynamic_cast( a );
^
@ubuntu:/mnt/hgfs/ub2$ ./a.out
terminate called after throwing an instance of 'std::bad_cast'
what(): std::bad_cast
Aborted (core dumped)
@ubuntu:/mnt/hgfs/ub2$
执行出现段错误是因为出现异常却没设法去捕获异常而造成的。这时候需要用到异常处理(之前所学内容例29),修改如下
#include#include #include using namespace std; class A{ public: virtual void show() { cout<<"aaaaaaa"< public: void show() { cout<<"bbbbbbbbbbbbaaaaaaa"< try{ A a; B &p = dynamic_cast( a ); } catch(bad_cast e) { cout< 这时候编译虽然警告,但最后能够成功执行
@ubuntu:/mnt/hgfs/ub2$ g++ cast9.cpp cast9.cpp: In function ‘int main()’: cast9.cpp:29:31: warning: dynamic_cast of ‘A a’ to ‘class B&’ can never succeed B &p = dynamic_cast( a ); ^ @ubuntu:/mnt/hgfs/ub2$ ./a.out std::bad_cast @ubuntu:/mnt/hgfs/ub2$2、自定义转换函数 例34、operator#include#include #include using namespace std; class Timer{ public: Timer() { hour = 0; min = 0; sec = 0; } ~Timer() { } void addtimer(int sec=1) { this->min += (this->sec+sec)/60; this->sec = (this->sec+sec)%60; } void show() { printf("%2d:%2d:%2dn", hour, min, sec); } Timer operator+(int sec) { Timer tem; tem.sec = this->sec+sec; return tem; } Timer operator+(Timer &x) { Timer tem; tem.sec = sec+x.sec; tem.min = min+x.min; tem.hour = hour+x.hour; return tem; } Timer operator++(int) { Timer tem = *this;//backup sec++; return tem; } Timer operator++() { sec++; return *this; } bool operator==(Timer &x) { if(sec==x.sec && min==x.min && hour==x.hour) return true; return false; } int &operator[](int i) { switch(i) { case 0: return hour; case 1: return min; case 2: return sec; } } //转换成int就operator int() operator int() { //实现相应的功能,此处是转成秒 return sec+min*60+hour*60*60; } friend ostream &operator<<(ostream &out, const Timer &t); private: int hour; int min; int sec; }; ostream &operator<<(ostream &out, const Timer &t) { out << "hour: "< Timer t; t.addtimer(3); int sec = t; //强转为整形类型 cout<< sec < 3、隐式构造 例35、explicit #includeusing namespace std; class mempool{ public: //构造函数 //mempool(int size){ //explicit隐式构造 explicit mempool(int size){ data = new char[size]; cout<< "cccccccccc" < delete [] data; } private: char *data; }; int main() { //调用构造函数 // mempool a(100); //在平常构造函数时无法去识别下式子是赋值100还是表示a大小为100,使用explicit隐式构造可以报错区分 mempool a = 100; } 错误提示
@ubuntu:/mnt/hgfs/ub2$ g++ mempool.cpp mempool.cpp: In function ‘int main()’: mempool.cpp:28:14: error: conversion from ‘int’ to non-scalar type ‘mempool’ requested mempool a = 100; ^~~ @ubuntu:/mnt/hgfs/ub2$



