C++的类型转换

前言

在学习C语言时大家应该都学过类型转换。在C语言里面有两个转换:

1,自动转换(隐式类型转换)。

隐式类型转换是在两个变量的类型意义差不多,具有一定关联的情况下发生的类型转换

2,强制类型转换。

强制类型转换便是在两个变量的意义不同但是具有一定关联的情况下可以被强制发生的转换

举例如下:

1,隐式类型转换

cpp 复制代码
int a = 1;
double d = a;//发生了隐式类型转换,d会调用临时对象拷贝构造a。

如何验证:利用引用的特性:引用不能放大权限去引用一个对象。

cpp 复制代码
double& b1 = a;//这段代码出现错误
const double& b2 = a;//这段代码没有出现错误

根据以上的代码的判断说明引用的对象是一个具有常属性的对象,但是a的类型是int类型没有const修饰。所以,一定就是生成了临时对象,也就是出现了类型转换。

2,强制类型转换(显示转换)

cpp 复制代码
int* p = &a;//p是一个地址,类型是int*
int b = (int)p;//强制转换

因为地址和整型是意义不一样的两个类型所以不会发生隐式类型转换。但是,由于地址也是一个整数,所以int和int*有一定的关联所以可以发生一个强制转换。

C++里面的类型转换

1,种类

在C++里面,类型转换分为以下四类:

1,static_cast<type>(variable): 隐式类型转换。

cpp 复制代码
int a = 1;
double b = static_cast<double>(a);//将a转换为double类型

2,reinterprete_cast<type>(variable):强制类型转换

cpp 复制代码
int* c = &a;
int d = reinterpret_cast<int>(c);//将c强制转化为int类型

3,const_cast<type*/type&>(variable):取消const属性,注意必须是指针或者引用才能转换

cpp 复制代码
const int e = 2;
int* f = const_cast<int*>(&e);//取小const int* 的const转换为int*。
*f = 3;

4,dynamic_cast<子type*/子type&>(variable):继承关系之间的的类型转换。

在这里需要明确两个概念:

继承的向上转型是一个隐式类型转换,比如子类的对象,引用,指针转化给父类的对象,指针,引用。

继承的向下转型父类指针或者父类引用转为子类指针,子类引用。(没有对象的强制转换)。

cpp 复制代码
class A
{
public:
	virtual void f1() {}
	int _a;
};

class B:public A
{
public:
	int _b;
};

void fun(A* x)
{
	B* pph1 = dynamic_cast<B*>(x);//检查转换,转换失败会返回一个NULL
	if (pph1)
	{
		pph1->_a = 1;
		pph1->_b = 2;
		cout << "转换成功" << endl;
	}
	else
	{
		cout << "转换错误" << endl;
	}
}

2,注意点

1.在使用dynamic_cast时,要在父类中实现一个虚方法:virtual f(){}

2.在使用父类指针/引用直接接收子类指针/引用时虽然不会报错,但是可能会修改一段不属于传入的指针指向的空间,导致修改时发生越界。

3.在出现这样一段代码时:

cpp 复制代码
    const int a = 1;
	int* p = const_cast<int*>(&a);
	*p = 3;


	cout << "a:" << a << endl;
	cout << "*p: " << *p << endl<<endl;

	cout << "&a: " << &a << endl;
	cout << "p: " << p << endl;
	return 0;

结果如下:

会发现这a的地址其实就是p指向的地址,但是在将p指向的地址修改为3后发现对a没有影响。这样的原因在于:a是一个const修饰的变量,编译器在访问a时默认不会到a的内存中取而是在寄存器中取,所以会得到原来未修改的值。打破方法在于在const前面加上一个volatile。但是打印时又会出现两个变量地址不一样的问题,但这是cout的问题改成printf就好了。

相关推荐
一只路人甲13 小时前
使用AI快速学习
学习
C++ 老炮儿的技术栈13 小时前
我们在设计tcp协议时,要传一个字符串过去,报文:头十长度十内容,是否要把‘\0‘也填入,长度是否包含‘\0‘
开发语言·数据结构·c++·mfc·c
传奇开心果编程13 小时前
【Rust入门练中学】第2课:变量、可变性与常量
开发语言·学习·rust
边境悍匪16 小时前
蜗牛学苑 Java 智能体学习 Day42|项目周开发技术汇总 1 思维导图复盘
java·开发语言·spring boot·学习·spring
Gyr016 小时前
浅刷了一遍51CTO软考题库客观题及其解析(4)
学习·软考·知识点·信息安全工程师
是隼人16 小时前
buuctf-pwn [NewStarCTF 2023 公开赛道]stack migration(64位栈迁移)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
ι:17 小时前
单相桥式全控整流仿真从零复现教学
windows·学习·matlab·simulink
传奇开心果编程17 小时前
【Rust入门练中学】 第3课:数据类型
开发语言·学习·rust
humors22118 小时前
今年我正在看、看完和还没看的书单(不定期更新)
学习·阅读·读书·书单·书籍
泡泡鱼(敲代码中)18 小时前
MySQL 学习笔记:DCL、函数与约束 —— 安全、效率、完整性的三板斧
开发语言·笔记·sql·学习·mysql·gitee