C++风格与C风格类型强转异同

简介: C++风格的强转:C++强制类型转换C风格的强制类型转换很容易理解,不管什么类型都可以直接进行转换,使用格式如下:目标类型 b = (目标类型) a; C++也是支持C风格的强制类型转换,但是C风格的强制类型转换可能会带来一些隐患,出现一些难以察觉的问题,所以C++又推出了四种新的强制类型转换来替代C风格的强制类型转换,降低使用风险。在C++中,新增了四个关键字static_cast、const_cast、reinterpret_cast和dynamic_cast,用于支持C++风格的强制类型转换。C++风格的强制类型转换能更清晰的表明它们要干什么,程序员只要看一眼这样的代码,立即

C风格的强转:

隐式转换(编译器自动转换)

会出现警告,精度丢失

代码:

#include <iostream>usingnamespacestd;
intmain(intargc, char*argv[])
{
charcc='X';
floatff=cc;    // 隐式转换,不会告警。doubledd=3.38;
longll=dd;    // 隐式转换,会告警。。}

输出:

强制类型转换

不会出现警告,精度丢失一样存在

代码:

#include <iostream>usingnamespacestd;
intmain(intargc, char*argv[])
{
charcc='X';
floatffc=static_cast<float>(cc);  // 显式地使用static_cast进行强制类型转换,不会告警。doubledd=3.38;
longllc=static_cast<long>(dd);  // 显式地使用static_cast进行强制类型转换,不会告警。inta=int(dd);
}

输出:

C++风格的强转:

C++强制类型转换

C风格的强制类型转换很容易理解,不管什么类型都可以直接进行转换,使用格式如下:

目标类型 b = (目标类型) a;

C++也是支持C风格的强制类型转换,但是C风格的强制类型转换可能会带来一些隐患,出现一些难以察觉的问题,所以C++又推出了四种新的强制类型转换来替代C风格的强制类型转换,降低使用风险。

在C++中,新增了四个关键字static_cast、const_cast、reinterpret_cast和dynamic_cast,用于支持C++风格的强制类型转换。

C++风格的强制类型转换能更清晰的表明它们要干什么,程序员只要一眼这样的代码,立即能知道强制转换的目的,并且在多态场景也只能使用C++风格的强制类型转换。

一、static_cast

static_cast是最常用的C++风格的强制类型转换,主要是为了执行那些较为合理的强制类型转换,使用格式如下:

static_cast<目标类型>(表达式);

用于基本内置数据类型之间的转换

C风格:编译器可能会提示警告信息

static_cast:不会提示警告信息

#include <iostream>usingnamespacestd;
intmain(intargc, char*argv[])
{
charcc='X';
floatff=cc;     // 隐式转换,不会告警。floatffc=static_cast<float>(cc);  // 显式地使用static_cast进行强制类型转换,不会告警。doubledd=3.38;
longll=dd;    // 隐式转换,会告警。longllc=static_cast<long>(dd);  // 显式地使用static_cast进行强制类型转换,不会告警。}

用于指针之间的转换

C风格:可用于各种类型指针之间的转换。

static_cast:各种类型指针之间的不允许转换,必须借助void*类型作为中间介质

#include <iostream>usingnamespacestd;
intmain(intargc, char*argv[])
{
inttype_int=10;
float*float_ptr1= (float*)&type_int; //C风格直接强转cout<<"C风格"<<"*float_ptr1 = "<<*float_ptr1<<endl;
// float* char_ptr2 = static_cast<float*>(&type_int); // int* -> char* 使用static_cast转换无效void*void_ptr=&type_int; // 任何指针都可以隐式转换为void*float*float_ptr4=static_cast<float*>(void_ptr); // void* -> float* 使用static_cast转换成功cout<<"C++风格"<<"*float_ptr4 = "<<*float_ptr4<<endl;
}

转换之后的数据是不精确的

不能转换掉expression的const或volitale属性

#include <iostream>intmain(intargc, char*argv[])
{
inttemp=10;
constint*a_const_ptr=&temp;
int*b_const_ptr=static_cast<int*>(a_const_ptr); // const int* -> int* 无效constinta_const_ref=10;
int&b_const_ref=static_cast<int&>(a_const_ref); // const int& -> int& 无效volatileint*a_vol_ptr=&temp;
int*b_vol_ptr=static_cast<int*>(a_vol_ptr); // volatile int* -> int* 无效volatileinta_vol_ref=10;
int&b_vol_ref=static_cast<int&>(a_vol_ref); // volatile int& -> int& 无效}

四种强转详解:

C++的类型转换只是语法上的解释,本质上与C风格的类型转换没什么不同,C语言做不到事情的C++也做不到。

语法:

static_cast<目标类型>(表达式);
const_cast<目标类型>(表达式);
reinterpret_cast<目标类型>(表达式);
dynamic_cast<目标类型>(表达式);

static_cast

用于内置数据类型之间的转换

除了语法不同,CC++没有区别。

#include <iostream>usingnamespacestd;
intmain(intargc, char*argv[])
{
intii=3;
longll=ii;                     // 绝对安全,可以隐式转换,不会出现警告。doubledd=1.23;
longll1=dd;                  // 可以隐式转换,但是,会出现可能丢失数据的警告。longll2= (long)dd;              // C风格:显式转换,不会出现警告。longll3=static_cast<long>(dd);    // C++风格:显式转换,不会出现警告。cout<<"ll1="<<ll1<<",ll2="<<ll2<<",ll3="<<ll3<<endl;
}

用于指针之间的转换

C风格可以把不同类型的指针进行转换。

C++不可以,需要借助void *

#include <iostream>usingnamespacestd;
voidfunc(void*ptr) {   // 其它类型指针 -> void *指针 -> 其它类型指针double*pp=static_cast<double*>(ptr);
}
intmain(intargc, char*argv[])
{
intii=10;
double*pd1=&ii;                          // 错误,不能隐式转换。double*pd2= (double*)&ii;                 // C风格,强制转换。double*pd3=static_cast<double*>(&ii);    // 错误,static_cast不支持不同类型指针的转换。void*pv=&ii;                             // 任何类型的指针都可以隐式转换成void*。double*pd4=static_cast<double*>(pv);     // static_cast可以把void *转换成其它类型的指针。func(&ii);

const_cast

static_cast不能丢掉指针(引用)的const和volitale属性,const_cast可以。

示例:

#include <iostream>usingnamespacestd;
intmain(intargc, char*argv[])
{
intnum=4;
constint*aa=&num;
int*bb= (int*)aa;                  // C风格,强制转换,丢掉const限定符。int*cc=const_cast<int*>(aa);      // C++风格,强制转换,丢掉const限定符。*bb=6;
cout<<*bb<<endl;
cout<<*cc<<endl;
}

输出:

6 6

三、reinterpret_cast

static_cast不能用于转换不同类型的指针(引用)(不考虑有继承关系的情况),reinterpret_cast可以。

reinterpret_cast的意思是重新解释,能够将一种对象类型转换为另一种,不管它们是否有关系。

语法:reinterpret_cast<目标类型>(表达式);

<目标类型>和(表达式)中必须有一个是指针(引用)类型。

reinterpret_cast不能丢掉(表达式)的const或volitale属性。

应用场景:

reinterpret_cast的第一种用途是改变指针(引用)的类型。

reinterpret_cast的第二种用途是将指针(引用)转换成整型变量。整型与指针占用的字节数必须一致,否则会出现警告,转换可能损失精度。

reinterpret_cast的第三种用途是将一个整型变量转换成指针(引用)。

示例:

#include <iostream>usingnamespacestd;
voidfunc(void*ptr) {  
longlongii=reinterpret_cast<longlong>(ptr);
cout<<"ii="<<ii<<endl;
}
intmain(intargc, char*argv[])
{
longlongii=10;
func(reinterpret_cast<void*>(ii));
}

输出:

4 4

完结撒花(注本文章部分采用慕课往的C++基础课的文档本人做一些总结如由侵权立即删除)

目录
相关文章
|
6月前
|
存储 程序员 C语言
c++primer plus 6 读书笔记 第四章 复合类型
c++primer plus 6 读书笔记 第四章 复合类型
|
2月前
|
存储 编译器 程序员
C++类型参数化
【10月更文挑战第1天】在 C++ 中,模板是实现类型参数化的主要工具,用于编写能处理多种数据类型的代码。模板分为函数模板和类模板。函数模板以 `template` 关键字定义,允许使用任意类型参数 `T`,并在调用时自动推导具体类型。类模板则定义泛型类,如动态数组,可在实例化时指定具体类型。模板还支持特化,为特定类型提供定制实现。模板在编译时实例化,需放置在头文件中以确保编译器可见。
39 11
|
3月前
|
安全 程序员 C语言
C++(四)类型强转
本文详细介绍了C++中的四种类型强制转换:`static_cast`、`reinterpret_cast`、`const_cast`和`dynamic_cast`。每种转换都有其特定用途和适用场景,如`static_cast`用于相关类型间的显式转换,`reinterpret_cast`用于低层内存布局操作,`const_cast`用于添加或移除`const`限定符,而`dynamic_cast`则用于运行时的类型检查和转换。通过具体示例展示了如何正确使用这四种转换操作符,帮助开发者更好地理解和掌握C++中的类型转换机制。
|
4月前
|
C++
使用 QML 类型系统注册 C++ 类型
使用 QML 类型系统注册 C++ 类型
100 0
|
5月前
|
编译器 C++ 运维
开发与运维函数问题之函数的返回类型如何解决
开发与运维函数问题之函数的返回类型如何解决
41 6
|
5月前
|
安全 编译器 C++
C++一分钟之-模板元编程实例:类型 traits
【7月更文挑战第15天】C++的模板元编程利用编译时计算提升性能,类型traits是其中的关键,用于查询和修改类型信息。文章探讨了如何使用和避免过度复杂化、误用模板特化及依赖特定编译器的问题。示例展示了`is_same`类型trait的实现,用于检查类型相等。通过`add_pointer`和`remove_reference`等traits,可以构建更复杂的类型转换逻辑。类型traits增强了代码效率和安全性,是深入C++编程的必备工具。
93 12
|
4月前
|
存储 C++
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
55 0
|
5月前
|
C++
C++一分钟之-类型别名与using声明
【7月更文挑战第20天】在C++中,类型别名和`using`声明提升代码清晰度与管理。类型别名简化复杂类型,如`using ComplexType = std::vector&lt;std::shared_ptr&lt;int&gt;&gt;;`,需注意命名清晰与适度使用。`using`声明引入命名空间成员,避免`using namespace std;`全局污染,宜局部与具体引入,如`using math::pi;`。恰当应用增强代码质量,规避常见陷阱。
90 5
|
4月前
|
设计模式 安全 IDE
C++从静态类型到单例模式
C++从静态类型到单例模式
40 0
|
5月前
|
C++ 开发者
C++一分钟之-概念(concepts):C++20的类型约束
【7月更文挑战第4天】C++20引入了Concepts,提升模板编程的类型约束和可读性。概念定义了模板参数需遵循的规则。常见问题包括过度约束、约束不完整和重载决议复杂性。避免问题的关键在于适度约束、全面覆盖约束条件和理解重载决议。示例展示了如何用Concepts限制模板函数接受的类型。概念将增强模板的安全性和灵活性,但需谨慎使用以防止错误。随着C++的发展,Concepts将成为必备工具。
112 2