C++的四种类型转换

文章目录

const_cast:去掉常量类型的类型转换

const_cast<>是语言级别上的检测,和C风格的强制转换在汇编代码上是一样的

c 复制代码
//C
const int a1 = 10;
double* p1 = (double*)&a1;
cpp 复制代码
//C++
int* p2 = const_cast<int*>(&a1);

const_cast只能用于去掉const属性,不弄用于类型转换

且const_cast<里面只能放指针和引用类型>

static_cast:提供编译器认为安全的类型转换(在编译阶段完成类型转换)

static_cast允许标准类型之间的相互转换和void*类型转换成其他指针类型

cpp 复制代码
int a = 10;
char b = static_cast<char>(a);
long c = static_cast<long>(a);
cpp 复制代码
int* p = nullptr;
short* b = static_cast<short*>(p);//错误

void* p1 = nullptr;
short* p2 = static_cast<short*>(p1);

reinterpret:类似c风格的强制类型转化

cpp 复制代码
int* k = nullptr;
//危险!容易照成未定义行为
short* b = reinterpret_cast<short*>(k);
double* j = reinterpret_cast<double*>(k);

原本指向四字节的int型k指针被强制转成八字节,多出那四字节可是未初始化的空间,当程序使用这块空间时会导致程序宕机

dynamic_cast:主要用在继承结构里,可以支持RTTI类型识别的上下转换

在程序运行时动态检查对象的实际类型。它会查询对象的RTTI信息(存储在虚函数表中)来判断转换是否合法

cpp 复制代码
class A
{
public:
	virtual void func() = 0;
};

class B : public A
{
public:
	void func() { std::cout << "call B::func" << std::endl; }
};

class C : public A
{
public:
	void func() { std::cout << "call C::func" << std::endl; }
	void C_uinque_func() {std::cout << "C unique func" << std:: endl; }
};

int main()
{

	B b1;
	C c1;

	show_func(&b1);
	show_func(&c1);

	return 0;
}

写一个show_func函数

cpp 复制代码
void show_func(A* p)
{
	p->func();
}

int main()
{

	B b1;
	C c1;

	show_func(&b1);
	show_func(&c1);

	return 0;
}

通过虚函数调用到两个派生类重写以后的函数的打印结果

当我们想实现传入子类C执行 C_uinque_func()函数

传入子类B执行func()函数时

可以把show_func()函数改成这样

cpp 复制代码
void show_func(A* p)
{
	C* pd2 = dynamic_cast<C*>(p);
	//若转换非法(B无法转换成C,这两个之间无继承关系)对指针返回nullptr
	if(pd2 != nullptr)
	{
		pd2->C_uinque_func();
	}
	else
	{
		p->func();
	}
}

int main()
{

	B b1;
	C c1;

	show_func(&b1);
	show_func(&c1);

	return 0;
}

此时就可以动态调用到子类C的函数

dynamic_cast<>仅对多态类型(含虚函数的类)有效

如果我们把基类A里的虚函数改为普通函数,

dynamic无法正常使用

多继承里的交叉转换

dynamic_cast 可以用于跨越不同基类分支的转换,前提是目标类型与对象实际类型兼容

cpp 复制代码
class Base1 
{
public:
	Base1(){std::cout << "this is Base1" << std::endl;}
	virtual ~Base1() {} 
};
class Base2 
{ 
public: 
	Base2(){std::cout << "this is Base2" << std::endl;}
	virtual ~Base2() {} 
};
class Derived : public Base1, public Base2 
{

};

int main()
{

	Base1* b1 = new Derived;
	// 合法,因为对象实际是Derived
	Base2* b2 = dynamic_cast<Base2*>(b1);

	return 0;
}

在类的转换时,在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的。在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全

相关推荐
我还记得那天1 分钟前
C语言递归实现汉诺塔问题
c语言·开发语言
不吃土豆的马铃薯3 分钟前
Spdlog 入门:日志记录器与日志槽基础详解
服务器·开发语言·c++·c·日志·spdlog
此生决int7 分钟前
算法从入门到精通——前缀和
c++·算法·蓝桥杯
凯瑟琳.奥古斯特12 分钟前
传输层核心功能解析
开发语言·网络·职场和发展
Fuyo_111927 分钟前
C++中的活字印刷术——模板·初阶
开发语言·c++·笔记
小白|28 分钟前
cmake:昇腾CANN构建系统完全指南
java·c++·算法
在角落发呆28 分钟前
跨越网络鸿沟:传统文件传输与现代内网穿透的奇妙交响
开发语言·php
王老师青少年编程29 分钟前
2026年全国青少年信息素养大赛“算法应用主题赛”(初赛)【C++考点大纲】(全场景、组别):文末附备考秘籍!
c++·全国青少年信息素养大赛·初赛·2026年·算法应用主题赛·考点大纲
Season45032 分钟前
C++之模板元编程(前置知识 constexpr)
开发语言·c++
AI玫瑰助手34 分钟前
Python运算符:比较运算符(等于不等等于大于小于)与返回值
android·开发语言·python