【C++特性】四种类型转

C语言转换

cpp 复制代码
#include <iostream>

int main() {
	int x = 256;
	char c1 = x;//隐式转换
	char x2 = (char)x;//显示转换
}

优点是简洁,代码书写方便,适合快速原型开发。缺点是安全性差:隐式转换可能造成数据截断或精度丢失,且不易被察觉;显式转换虽然意图明确,但同样缺乏类型检查,容易埋下隐患。因此在实际工程中,应尽量避免使用 C 风格转换,转而使用 C++ 提供的类型转换运算符。# C++的4种方式

C++ 风格转换语法冗长,书写繁琐,有意"恶心"程序员,目的是让转换操作在代码中显得突兀、醒目。这样一旦程序出现缺陷,开发者能第一时间联想到可能是类型转换出了问题,从而快速定位。优点是安全性高:每种转换运算符都有明确的适用场景和检查机制,编译器能在编译期或运行期发现错误,避免静默的数据损坏。## 静态转换(static_cast)

static_cast 是最基础、最常用的转换运算符,用于编译期可确定的类型安全转换,全程无运行时类型检查,因此没有任何运行时性能开销,仅在编译期完成类型转换处理。它适用于:基础类型之间的转换(如 int 转 char、float 转 int)、任意指针与 void* 之间的互转、上行转换(派生类转基类)等。需要注意的是,static_cast 不执行运行时安全检查,若用于下行转换(基类转派生类),程序员必须自行保证对象实际类型正确,否则会产生未定义行为。

cpp 复制代码
#include <iostream>

class CStr : public std::string {

};

int main() {
	// 1. 基础类型的转换
	int num = 65;
	char ch = static_cast<char>(num);
	//任意指针与void*之间的转换
	int value = 42;
	int* intPtr = &value;
	void* voidPtr = static_cast<void*>(intPtr);
	//上行转换(Upcasting),派生类转成基类
	CStr str;
	std::string* pStr = &str;
	//下线转换:基类转成父类,有可能出错
	std::string str2;
	CStr* pStr2 = static_cast<CStr*>(&str2);
}

动态转换dynamic_cast

dynamic_cast 是运行时类型识别(RTTI)的核心工具,用于在继承层次中进行安全的向下转换和交叉转换。使用它必须满足以下条件:

  1. 基类必须包含至少一个虚函数,否则无法使用 dynamic_cast,编译器会报错(因为 RTTI 依赖虚表)。
  2. 禁止在构造函数和析构函数中使用 dynamic_cast,此时对象的虚表还未完全构建或已开始销毁,转换结果不可预期。
  3. 频繁使用 dynamic_cast 会影响程序性能,因为它需要运行时遍历继承链进行类型比对;在核心高频场景,可通过虚函数多态或其他设计模式(如访问者模式)替代下行转换,避免性能损耗。

转换失败的处理方式:指针转换失败返回 nullptr,引用转换失败抛出 std::bad_cast 异常。因此使用引用转换时,必须用 try-catch 包裹,否则程序会直接崩溃。## 基类必须有虚函数

cpp 复制代码
#include <iostream>

class CStr : public std::string {

};

int main() {	

	std::string str2;
	CStr* pStr2 = dynamic_cast<CStr*>(&str2);
}

编译上述代码,VS2019 会报出如下错误:

复制代码
严重性	代码	说明	项目	文件	行	禁止显示状态
错误(活动)	E0698	运行时 dynamic_cast 的操作数必须包含多态类类型

这是因为 std::string 没有虚函数,不是多态类型,编译器无法为其生成 RTTI 信息,因此 dynamic_cast 无法工作。解决办法是:确保基类至少含有一个虚函数(如虚析构函数),或者改用 static_cast 并自行保证类型安全。

指针转换失败

指针转换失败会,返回nullptr。如以下代码:

cpp 复制代码
#include <iostream>

class A {
	virtual int Age() { return 0; };
};
class B :A {
	
};

int main() {	

	A a;
	B* b= dynamic_cast<B*>(&a);
}

引用转换失败

引用转换失败会崩溃。如以下代码:

cpp 复制代码
int main() {	

	A a;
	B& b= dynamic_cast<B&>(a);
}

const_cast

取消掉常属性。

cpp 复制代码
#include <iostream>

void Out(int& x) {
	std::cout << x << std::endl;
}

int main() {	

	const int a=3;
	Out(const_cast<int&>(a));
}

只是让编译能通过,仍然是常量。

重新解释转换(reinterpret_cast)

不做任何编译时,运行时检测。由程序员保证正确性。非底层库勿用。

cpp 复制代码
#include <iostream>

int main() {	
	int a;
	std::string str;
	//无关类型转换
	int* p = reinterpret_cast<int*>(&str);
	//执行和整数互转
	int adr = reinterpret_cast<int>(&str);
	std::string* pStr = reinterpret_cast<std::string*>(adr);
}

扩展阅读

计算几何为骨,排样优化为魂
作品一:亲士套料工具箱 作品二: 亲士CAD工具箱
经典文章推荐:二维排样
万物皆数学
查阅鄙人的博文,请点击博文下载学院导航
活到老,学到老。明朝中后期,大约50%的进士能当上堂官(副部及更高);能当上堂官的举人只有十余人。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。

测试环境

操作系统:win7 开发环境: VS2019 C++17

或者 操作系统:win10 开发环境: VS2022 C++17

如无特殊说明,本算法用**C++**实现。

相关推荐
喵本喵叁肆22 分钟前
用 Boosting 把弱隐私算法炼成强隐私算法(英文原题:Boosting and Differential Privacy (FOCS 2010))
算法·集成学习·boosting
青梅味猪大肠1 小时前
【操作系统-60】临近适应算法
java·linux·开发语言·嵌入式硬件·算法·操作系统
apcipot_rain3 小时前
C++转Java日记(02)
java·开发语言·c++
杜 硕4 小时前
从零开始的C++生活——第七讲——02
开发语言·c++·生活
Rabitebla12 小时前
【Linux 底层原理】进程(十):进程等待详解---从僵尸进程到 wait、waitpid 与 status
linux·c++·笔记·学习·visual studio
西西弗Sisyphus14 小时前
C++ 超时互斥锁(Timed Mutex):std::timed_mutex 与 std::unique_lock
c++
其实防守也摸鱼16 小时前
个人学习 Pwn 思路:从基础到漏洞利用的进阶路径
大数据·前端·人工智能·chrome·算法·安全·网络安全
今天要早睡_16 小时前
C++01_入门基础复习
开发语言·c++