C++中的类型转换分两种:隐式类型转换和显式类型转换。
隐式转换,是标准的转换,很多时候是默认情况下由编译器进行转换;
显式转换,在C++中有四个类型的转换符:static_cast、dynamic_cast、const_cast、reinterpret_cast。
转换格式:
static_cast
(expression)
【1】上行转换,子类指针或引用转父类,这种转换是安全的。
多态类型之间转换:使用static_cast和使用dynamic_cast效果一样;
非多态类型之间转换:只能使用static_cast,使用dynamic_cast会编译报错;
- //先定义一个父类A,和子类B
- class A
- {
- public:
- virtual void Func() { cout << "A::Func()" << endl; }
- };
-
- class B : public A
- {
- public:
- void Func() override { cout << "B::Func()" << endl; }
- };
-
- int main()
- {
- A* pa = new B;
- A* a = static_cast(pb);//ok,转换是安全的
-
- B* pb = new B;
- A* a = static_cast(pb);//ok,转换是安全的
- return 0;
- }
【2】下行转换,父类指针或引用转子类,这种转换是不安全的
- int main()
- {
- //B* pb = new A; //error,编译报错,无法从A*转换为B*
- A* pa = new A;
- B* b = static_cast(pa); //ok,编译无误,b != nullptr,这是不安全的,没有做类型检查
- return 0;
- }
char转int,是安全的
- int iVar1 = 10;
- char cVar1 = 'a';
- iVar1 = static_cast<int>(cVar1);
- cout << iVar1 << endl;
int转char,是不安全的,由ASSIC表得出,只有int[32,126]区间,转换才是安全的
- int iVar2 = 10;
- char cVar2 = 'a';
- cVar2 = static_cast<char>(iVar2);
- cout << cVar2 << endl;
- int a = 10;
- void* pa = &a;
-
- int b = static_cast<int>(pa);
- cout << b << endl;
-
- float c = static_cast<float>(pa);
- cout << c << endl;

- const int iVar = 110;
- int* pVar1 = static_cast<int*>(&iVar);//编译报错
- const int* pVar2 = static_cast<const int*>(&iVar);//编译无误,通过

转换格式:
dynamic_cast
(expression)
【1】上行转换(单继承),子类指针或引用转父类,这种转换是安全的。
多态类型之间转换:使用static_cast和使用dynamic_cast效果一样;
非多态类型之间转换:只能使用static_cast,使用dynamic_cast会编译报错;
- class A
- {
- public:
- virtual void Func(){cout << "A::Func()" << endl;}
- };
-
- class B: public A
- {
- public:
- virtual void Func() override{cout << "B::Func()" << endl;}
- };
-
- int main()
- {
- B* pb = new B;
- A* a1 = dynamic_cast(pb); //OK
- a1->Func();
-
- A* pa = new B;
- A* a2 = dynamic_cast(pa); //OK
- a2->Func();
- return 0;
- }
如果Func为virtual,输出结果: 
如果Func为非virtual,输出结果: 
【2】上行转换(多重继承),子类指针或引用转父类,这种转换是安全的
- class A
- {
- public:
- virtual void Func(){}
- };
-
- class B: public A
- {
- public:
- virtual void Func() override{}
- };
-
- class C : public B
- {
- public:
- virtual void Func() override{}
- };
-
- int main()
- {
- C* c = new C;
- B* b = dynamic_cast(c); //OK
- A* a = dynamic_cast(c); //OK
- }
原因,类中存在虚函数,说明有想让基类指针或引用指向派生类对象的情况,此时转换才有意义;由于运行时类型检查需要运行时类型信息(该运行信息存储在类的虚函数表中),所以只有定义了虚函数的类才有虚函数表。
- class A
- {
- public:
- virtual void Func() {} //注意关键字virtual
- // ......
- };
- class B : public A
- {
- public:
- virtual void Func() {} //注意关键字virtual
- // ......
- };
- int main()
- {
- A *pA = new A;
- B *pB = new B;
- void *pV = dynamic_cast<void *>(pA); // pV points to an object of A
- pV = dynamic_cast<void *>(pB); // pV points to an object of B
-
- system("pause");
- return 0;
- }
去掉virtual关键字,会编译报错

【1】下行转换(单继承),父类指针或引用转子类,会做类型安全检查,这种转换是安全的
- class A
- {
- public:
- virtual void Func(){cout << "A::Func()" << endl;}
- };
-
- class B: public A
- {
- public:
- virtual void Func() override{cout << "B::Func()" << endl;}
- };
-
- int main()
- {
- //B* pb = new A; //error,编译报错,无法从父类A*转换为子类B*
-
- /*
- * 由父类A*转换子类B*,使用dynamic_cast能做到安全检查,转换失败会返回null;
- * 使用static_cast不安全
- */
- A* pa1 = new B;
- B* b1 = dynamic_cast(pa1); //ok,编译无误,b != nullptr
- if (nullptr != b1)
- {
- b1->Func();
- }
-
- A* pa2 = new A;
- B* b2 = dynamic_cast(pa2); //ok,编译无误,b = nullptr
- if (nullptr != b2)
- {
- b2->Func();
- }
- return 0;
- }
【2】 对于一些复杂继承关系,使用dynamic_cast进行转换是存在一些陷阱的
如下做法存在陷阱,
- class A
- {
- virtual void Func() = 0;
- };
- class B : public A
- {
- void Func() { cout << "B::Func()" << endl; }
- };
- class C : public A
- {
- void Func() { cout << "C::Func()" << endl; };
- };
- class D : public B, public C
- {
- void Func() { cout << "D::Func()" << endl; }
- };
- int main()
- {
- D *pD = new D;
-
- /*
- * B和C都继承了A,并且都实现了虚函数Func,导致在进行转换时,无法进行抉择应该向哪个A进行转换
- */
- A *pA = dynamic_cast(pD); // pA = NULL
- //pA->Func();
-
- system("pause");
- return 0;
- }
正确的做法是,像多重继承关系这种情况,需要把子类逐步转换到父类
- int main()
- {
- D *pD = new D;
- B *pB = dynamic_cast(pD);
- A *pA = dynamic_cast(pB);
- return 0;
- }
转换格式:const_cast用来将类型的const、volatile和_unaligned属性移除。
const_cast
(expression)
- class A
- {
- public:
- A() :m_iA(10) {}
- int m_iA;
- };
- int main()
- {
- //常量指针转非常量指针
- const A *pA = new A;
- //pA->m_iA = 100; //error,pA常量指针,指向的内容不能修改
- cout << pA->m_iA << endl;
-
- A *pB = const_cast(pA); //去const属性
- pB->m_iA = 100; //通过指针,修改值
-
- //指针pA和pB指向同一个对象
- cout << pA->m_iA << endl;
- cout << pB->m_iA << endl;
-
- return 0;
- }
- class A
- {
- public:
- A() :m_iA(10) {}
- int m_iA;
- };
-
- int main()
- {
- //常量指针转非常量指针
- A * const pA1 = new A;
- pA1->m_iA = 100; //ok,pA是指针常量,指向的内容可以修改
- cout << pA1->m_iA << endl;
-
- A *pA2 = new A;
- //pA1 = pA2; //error,pA是指针常量,指向的地址不能修改
-
- A *pB = const_cast(pA1); //去const属性
- pB = pA2; //通过指针,修改值
- pB->m_iA = 111;
-
- //指针pA和pB指向同一个对象
- cout << pA1->m_iA << endl;
- cout << pA2->m_iA << endl;
- cout << pB->m_iA << endl;
-
- return 0;
- }
- int main()
- {
- const int &num = 10;
- //num = 100; //error,不能给常量赋值
- int &num2 = const_cast<int&>(num);
- num2 = 100;
- return 0;
- }
- int main()
- {
- const int num1 = 10;
- //int num2 = const_cast<int>(num1); //error,编译报错,无法从“const int”转换为“int”
- return 0;
- }
转换格式:
reinterpret_cast
(expression)
reinterpret_cast后的尖括号中的type-id类型必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针。