C++ - 新增的类型转换

1.C方式的强制类型转换存在的问题

过于粗暴:任何类型之间都可以进行转换,编译器很难判断其正确性。
难于定位:在源码中无法快速定位所以使用强制类型转换的语句。

隐式类型的转换和强制转换

所谓的隐式类型的强转就是相近的类型的转化,强制转换就是讲类型

如下:

int main()
{
    int i = 1;
    double j = i;
    printf("%d,%2f\n", i, j); //隐式
 
    int *p = &i;
   int address = (int)p://强转
    printf("%x,%d\n",p,address);
    system("pause");
    return 0;
}

2.C++新增的4种不同类型的强制类型转换。

static_cast强制类型转换:int转flaot,double转int等等。
-> 用于基本类型间的转换。
-> 不能用于基本类型指针间的转换。
-> 用于有继承关系类对象之间的转换和类指针之间的转换。

void Tes1()
{
    int i = 2;
    double j = static_cast<double>(i);
    printf("%d,%2f\n", i,j);
}

const_cast强制类型转换:去常性
-> 用于去除变量的只读属性。
-> 强制转换的目标类型必须是指针或引用。

void Test3()
{
    const int a = 2;
    int *p = const_cast<int *>(&a);
    *p = 3;
    printf("%d", a);
}

reinterpret_cast强制类型转换:
-> 用于指针类型间的强制转换。
-> 用于整数和指针类型间的强制转换。

void Test2()
{
    int i = 10;
    int *j = &i;
    int address = reinterpret_cast<int>(j);
    printf("%d,%d", i, j);
 
}

dynamic_cast强制类型转换:
-> 用于有继承关系的类指针间的转换。
-> 用于有交叉关系的类指针间的转换。
-> 具有类型检查的功能。
-> 需要虚函数的支持。

【作用】:将一个基类对象指针(或引用)cast到继承类指针,dynamic_cast会根据基类指针是否真正指向继承类指针来做相应处理, 即会作出一定的判断。
若对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针;
若对引用进行dynamic_cast,失败抛出一个异常,成功返回正常cast后的对象引用。
【注意】:
1、dynamic_cast在将父类cast到子类时,父类必须要有虚函数,否则编译器会报错。
2、 dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;
在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。


下面通过一个简单的例子来说明dynamic_cast的作用:


#include <iostream>
#include <assert.h>
 
using namespace std;
 
// 我是父类
class Tfather
{
public:
	virtual void f() { cout << "father's f()" << endl; }
};
 
// 我是子类
class Tson : public Tfather
{
public:
	void f() { cout << "son's f()" << endl; }
 
	int data; // 我是子类独有成员
};
 
int main()
{ 
	Tfather father;
	Tson son;
	son.data = 123;
 
	Tfather *pf;
	Tson *ps;
	
	/* 上行转换:没有问题,多态有效 */
	ps = &son;
	pf = dynamic_cast<Tfather *>(ps);
	pf->f();
 
	/* 下行转换(pf实际指向子类对象):没有问题 */
	pf = &son;
	ps = dynamic_cast<Tson *>(pf);
	ps->f();
	cout << ps->data << endl;		// 访问子类独有成员有效
 
	/* 下行转换(pf实际指向父类对象):含有不安全操作,dynamic_cast发挥作用返回NULL */
	pf = &father;
	ps = dynamic_cast<Tson *>(pf);
	assert(ps != NULL);			 	// 违背断言,阻止以下不安全操作
	ps->f();
	cout << ps->data << endl;		// 不安全操作,对象实例根本没有data成员
 
	/* 下行转换(pf实际指向父类对象):含有不安全操作,static_cast无视 */
	pf = &father;
	ps = static_cast<Tson *>(pf);
	assert(ps != NULL);
	ps->f();
	cout << ps->data << endl;		// 不安全操作,对象实例根本没有data成员
 
	system("pause");
}

小结:

C方式的强制类型转换:
-> 过于粗暴,潜在的问题不易被发现,不易在代码中定位。

新式类型转换以C++关键字的方式出现:
-> 编译器能够帮助检查潜在的问题。
-> 非常方便的在代码中定位。
-> 支持动态类型识别。

c++强制类型转换_f2016913的博客-CSDN博客

C和C++的强制类型转换_RightJay的博客-CSDN博客

dynamic_cast用法总结_weixin_44212574的博客-CSDN博客_dynamic_cast

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式_笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值