• static_cast
  • interpret_cast
  • const_cast
  • dynamic_cast

各种cast可以评估风险等级,有利于查找程序出错的地方

static_cast

image.png

  1. #include <iostream>
  2. using namespace std;
  3. class A {
  4. public:
  5. operator int() {return 1;}
  6. operator char*() {return NULL;}
  7. };
  8. int main() {
  9. A a;
  10. int n; char* p = "new Dragon Inn";
  11. n = static_cast<int>(3.14); // n的值为3
  12. n = static_cast<int>(a); // 调用a.operator int, n的值为1
  13. p = static_cast<char*>(a); // 调用a.operator char* p的值为NULL
  14. n = static_cast<int> (p); // 编译错误,static_cast不能将指针转换成整型
  15. p = static_cast<char*>(n); // 编译错误
  16. return 0;
  17. }

reinterpret_cast

image.png

  1. #include <iostream>
  2. using namespace std;
  3. class A {
  4. public:
  5. int i;
  6. int j;
  7. A(int n):i(n), j(n){}
  8. };
  9. int main() {
  10. A a(100);
  11. int & r = reinterpret_cast<int&>(a); // 强行让r引用a
  12. r = 200; // 把a.i变成200
  13. cout << a.i << "," << a.j << endl; // 输出200,100
  14. int n = 300;
  15. A * pa = reinterpret_cast<A*>(& n); // 强行让pa指向n
  16. pa->i = 400; // n变成400
  17. pa->j = 500; // 不安全,很可能崩溃
  18. cout << n << endl; // 输出400
  19. long long la = 0x12345678abcdLL;
  20. pa = reinterpret_cast<A*>(la); // la太长,只能取低32为0x5678abcd拷贝给pa
  21. // 在64位的机器上不行,因为指针是64位的,而unsigned int 是32位的
  22. unsigned int u = reinterpret_cast<unsigned int>(pa); // pa逐个比特拷贝给u
  23. cout << hex << u << endl; // 输出5678abcd
  24. typedef void (* PF1)(int);
  25. typedef int (* PF2)(int, char*);
  26. PF1 pf1; PF2 pf2;
  27. pf2 = reinterpret_cast<PF2>(pf1); // 两个不同类型的函数指针
  28. }

const_cast

image.png

dynamic_cast

image.png
dynamic_cast是通过检查虚函数表的指针来判断该类是否为多态类的

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. class Base {
  5. public:
  6. virtual Base() {}
  7. };
  8. class Derived: public Base {
  9. };
  10. int main() {
  11. Base b;
  12. Derived d;
  13. Derived * pd;
  14. pd = reinterpret_cast<Derived *>(&b);
  15. if(pd == NULL) //此处pd不会为NULL。 reinterpret_cast不检查安全性,总是进行转换
  16. // 不会执行
  17. cout << "unsate interpret_cast" << endl;
  18. pd = dynamic_cast<Derived *> (&b);
  19. if(pd == NULL) //结果会是NULL,因为 &b不是指向派生类对象,此转换不安全
  20. cout << "unsafe dynamic_cast1" << endl; // 会执行
  21. Base * pb = & d;
  22. pd = dynamic_cast<Derived*>(pb); // 安全的转换
  23. if(pd == NULL)
  24. cout << "unsafe dynamic_cast2" << endl; // 不会执行
  25. return 0;
  26. }

image.png