C++深度解析(8)—C++新型的类型转换

1.强制类型转换 

  • C方式的强制类型转换 
    • (Type) (Expression) 
    • Type (Expression)
#include <stdio.h>  
  
typedef void(PF)(int);  
  
struct Point  
{  
    int x;  
    int y;  
};  
  
int main()  
{  
    int v = 0x12345;  
    PF* pf = (PF*)v;  
    char c = char(v);  
    Point* p = (Point*)v;  
      
    pf(5);  
      
    printf("p->x = %d\n", p->x);  
    printf("p->y = %d\n", p->y);  
  
    return 0;  
} 

  • C方式强制类型转换存在的问题 
    • 过于粗暴:任意类型之间都可以进行转换,编译器很难判断其正确性 
    • 难于定位 :在源码中无法快速定位所有使用强制类型转换的语句 
  • 强制类型转换在实际工程中是很难完全避免的!如何进行更加安全可靠的转换?

2.新式类型转换 

  • C++将强制类型转换分为4种不同的类型 

  • type:是要转换的目标类型;expression:要转换的值

2.1 static_cast强制类型转换 

  • 用于基本类型间的转换 ,不能用于基本类型指针间的转换 
  • 用于有继承关系类对象之间的转换和类指针之间的转换
#include <stdio.h>

int main()
{
    int i = 0x12345;
    char c = 'c';
    int *pi = &i;
    char *pc = &c;
    
    c = static_cast<char>(i);    // static_cast用于基本类型间的转换,但不能用于基本类型指针间的转换
    pc = static_cast<char *>(pi);  // error,不能用于基本类型指针之间的转换
    
    printf("Press any key to continue...");
    
	getchar();
    
	return 0;
}

2.2 const_cast强制类型转换 

  • 用于去除变量的只读属性,强制转换的目标类型必须是指针引用
#include <stdio.h>

int main()
{
    const int &j = 1;
    int &k = const_cast<int &>(j);    // 将只读变量j降级为普通变量
    const int x = 2;
    int &y = const_cast<int &>(x);    // y时x常量地址的别名
       
    k = 5; 
    
    printf("k = %d\n", k);
    printf("j = %d\n", j);
    
    y = 8;

    printf("x = %d\n", x);      // 从符号表中直接取出2     
    printf("y = %d\n", y);
    printf("&x = %p\n", &x);
    printf("&y = %p\n", &y);
    
    printf("Press any key to continue...");
    
	getchar();
    
	return 0;
}
  • 运行结果

2.3 reinterpret_cast强制类型转换 

  • 用于指针类型间的强制转换 
  • 用于整数和指针类型间的强制转换
#include <stdio.h>

int main()
{
    int i = 0;
    char c = 'c';
    int *pi = &i;
    char *pc = &c;
    
    pc = reinterpret_cast<char *>(pi);
    pi = reinterpret_cast<int *>(pc);
    
    // c = reinterpret_cast<char>(i); // Oops!
    
    printf("Press any key to continue...");
    
	getchar();
    
	return 0;
}

2.4 dynamic_cast强制类型转换 

  • 用于有继承关系的类指针间的转换 
  • 用于有交叉关系的类指针间的转换 
  • 具有类型检查的功能 
  • 需要虚函数的支持 

3.关于继承中的强制类型转换 

  • 继承中如何正确的使用强制类型转换?
  • dynamic_cast是与继承相关的类型转换关键字 
  • dynamic_cast要求相关的类中必须有虚函数 
  • 用于有直接或者间接继承关系的指针(引用)之间 
    • 指针:转换成功:得到目标类型的指针; 转换失败:得到一个空指针 
    • 引用: 转换成功:得到目标类型的引用 ;转换失败:得到一个异常操作信息
  • 编译器会检查dynamic_cast的使用是否正确 
  • 类型转换的结果只可能在运行阶段才能得到
#include <iostream>
 
using namespace std;
 
class Base
{
public:
    Base()
    {
        cout << "Base::Base()" << endl;
    }
 
    virtual ~Base()
    {
        cout << "Base::~Base()" << endl;
    }
};
 
class Derived : public Base
{
 
};
 
int main()
{
    Base *p = new Base;
 
    Derived *pd = dynamic_cast<Derived*>(p);  //编译成功,转换失败返回0
 
    if( pd != NULL )
    {
        cout << "pd = " << pd << endl;
    }
    else
    {
        cout << "Cast error!" << endl;
    }
 
    Base* p1 = new Derived();
 
    Derived* pd1 = dynamic_cast<Derived*>(p1);//转换成功
 
    if( pd1 != NULL )
    {
        cout << "pd1 = " << pd1 << endl;
    }
    else
    {
        cout << "Cast error!" << endl;
    }
 
    delete p;
    delete p1;
 
    return 0;
}
  • 运行结果

4.小结

  • C方式的强制类型转换 
    • 过于粗暴
    • 潜在的问题不易被发现 
    • 不易在代码中定位 
  •  新式类型转换以C++关键字的方式出现 
    • 编译器能够帮助检查潜在的问题 
    • 非常方便的在代码中定位 
    • 支持动态类型识别(dynamic_cast) 
  • dynamic_cast是与继承相关的专用转换关键字 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值