5. 数据类型转换
1. C++ 中的新式类型转换
const_cast、static_cast、dynamic_cast、reinterpret_cast
1.1 const_cast
- 主要用来解除常指针和常量的 const 属性,即 const type* ⇒ type*,const type& ⇒ type&。
- const_cast 取消的是间接引用时的只读限制。
这里有个问题:为啥通过指针 p 改变了 a 的值,但是 a 还是 10?因为 a 的值是从符号表中直接取得。
1.2 static_cast
- 用于基本数据类型之间的转换,父子类对象之间的指针(或引用)的转换,一般指针和 void* 之间的转换等。
- 类类型之间的转换必须存在继承关系。
- 静态转换,编译时就决定。
- 在 C++ 中,指向子类对象的指针可以隐式转换为指向父类对象的指针,而反过来,就需要借助 static_cast。
上面的程序,A 和 B 没有继承关系。如果有继承关系,如下:隐式转换,子进程转父进程:
父进程转子进程如下:
1.3 dynamic_cast
- 用于 有继承关系的类指针 间的转换。
- 用于 有交叉关系的类指针 间的转换。
- dynamic_cast 所操作的指针或引用的对象必须用于虚函数,否咋编译报错。
#include <iostream>
using namespace std;class Base
{
public:Base() {}virtual ~Base() {}
};class Derived : public Base
{};int main()
{Base* p = new Base();Derived* pd = dynamic_cast<Derived*>(p);if (pd != NULL) {cout << "pd = " << pd << endl;} else {cout << "Cast error!" << endl;}delete p;return 0;
}
这里:子类转父类叫向上。
#include <iostream>
using namespace std;class A {
public:virtual funcA() {}
};class B : public A{
public:virtual funcB() {}
};class C : public B{
public:virtual funcC() {}
};class D :public C {
public:virtual funcD() {}
};int main(){A* pA;B* pB;C* pC;D* pD = new D;pA = dynamic_cast<A*>(pD); //向上转型成功if (pA == NULL){cout<<"failed: D* to A*"<<endl;} else {cout<<"successfully: D* to A*"<<endl;}pB = dynamic_cast<B*>(pD); //向上转型成功if (pB == NULL){cout<<"failed: D* to B*"<<endl;} else {cout<<"successfully: D* to B*"<<endl;}pC = dynamic_cast<C*>(pD); //向上转型成功if (pC == NULL){cout<<"failed: D* to C*"<<endl;} else {cout<<"successfully: D* to C*"<<endl;}cout << endl;delete pD;return 0;
}
#include <iostream>
using namespace std;class A {
public:virtual funcA() {}
};class B : public A{
public:virtual funcB() {}
};class C : public B{
public:virtual funcC() {}
};class D :public C {
public:virtual funcD() {}
};int main(){A* pA = new A;B* pB;C* pC;D* pD;pB = dynamic_cast<B*>(pA); //向下转型失败if (pB == NULL){cout<<" failed: A* to B*"<<endl;} else {cout<<" successfully: A* to B*"<<endl;}pC = dynamic_cast<C*>(pA); //向下转型失败if (pC == NULL){cout<<" failed: A* to C*"<<endl;} else {cout<<" successfully: A* to C*"<<endl;}pD = dynamic_cast<D*>(pA); //向下转型失败if (pD == NULL){cout<<" failed: A* to D*"<<endl;} else {cout<<" successfully: A* to D*"<<endl;}cout << endl;delete pA;return 0;
}
1.4 reinterpret_cast
- 用于 指针类型间 的强制类型转换。
- 用于 整数 和 指针类型 间的强制转换。
- 是一种最大能力的转换。
#include <iostream>
using namespace std;int main()
{int i = 0;char c = 'c';int* pi = &i;char* pc = &c;pc = reinterpret_cast<char*>(pi);pi = reinterpret_cast<int*>(pc);pi = reinterpret_cast<int*>(i);// c = reinterpret_cast<char>(i); // 编译报错,基本类型之间应该用static_cast return 0;
}