全面盘点C++类型转换

2023-12-06 18:48:30 浏览数 (1)

全面盘点C 类型转换

  • 1.隐式转换
  • 2.显式转换
    • 2.1 C风格
    • 2.2 旧的C 风格
  • 3.强制类型转换操作符
    • 3.1 static_cast
    • 3.2 dynamic_cast
    • 3.3 const_cast
    • 3.4 reinterpret_cast

首先抛出一个面试问题,Type Conversion与Type Casting一样?

那么我们先来解答这第一个问题,这两者各自是什么?

1.Type Conversion

它包括显式与隐式。显式可以理解为通常所说的Casting。

2.Type Casting

Type Casting是通过使用强制转换操作符将一个值从一种数据类型显式转换为另一种数据类型。类型转换是由程序员显式使用强制转换操作符执行的。在C 中有四种类型的类型转换,即static_cast、dynamic_cast、reinterpret_cast和const_cast。

例如:字符串转整数、指针不同类型之间的转换。

如下图所示:

1.隐式转换

当涉及到C 中的隐式类型转换时,这是一种由编译器自动执行的过程,无需程序员显式指示。语法规则:

代码语言:javascript复制
var1 = value;
var2 = val1;

将数据从一种数据类型转换为另一种数据类型的行为可能会导致数据丢失。当较大数据类型的值转换为属于较小数据类型的值时,就会出现这种情况。

每种数据类型都有一个可以保存的特定值范围,具体取决于内存中用于表示它的位数。与较小的数据类型(如 int 或 char)相比,较大的数据类型(如 long long 或 double)可以容纳更广泛的值范围。当一个值从较大类型转换为较小类型时,原始值可能不适合较小类型的范围。这可能会导致信息丢失。例如:double 的小数部分将被截断,导致精度损失。

代码语言:javascript复制
double doubleValue = 1.666;
int intValue = doubleValue; 

但是反过来,就是ok的。

2.显式转换

显式转换也被称之为类型强制转换(type casting),包含C风格的转换、旧的C 风格转换、C operators。

2.1 C风格

语法:

代码语言:javascript复制
目标类型(变量);

我们只需要(),便可以实现显式转换。

例如:

代码语言:javascript复制
double d = 3.666;
int i = (int) d;

2.2 旧的C 风格

还有一种类似函数风格,语法:

代码语言:javascript复制
cast_type(expression);

例如:

代码语言:javascript复制
double d = 3.666;
int intValue = int(d); 

3.强制类型转换操作符

  • static_cast
  • const_cast
  • dynamic_cast
  • reinterpret_cast

3.1 static_cast

语法:

后面的cast语法与这个类似,后面就不赘述了,只需要将static_cast变为后面的cast即可。

代码语言:javascript复制
static_cast <dest_type> (source);

例如:

代码语言:javascript复制
int i = 1;
double d = static_cast<double>(i);

戳重点:static_cast不执行运行时检查。

3.2 dynamic_cast

当你不知道对象的动态类型时,dynamic_cast转换非常有用。如果引用的对象不包含转换为基类的类型,则返回空指针(当转换为引用时,在这种情况下会抛出错误的转换异常)。

向上强制转换(强制转换为基类)对于static_cast和dynamic_cast总是有效的,也可以不进行任何强制转换,因为向上强制转换是隐式转换(假设基类是可访问的,即它是公共继承)。

例如:

代码语言:javascript复制
Base* base = new Derived;
Derived* d = dynamic_cast<Derived*>(base);
if (d) {
  d->print();
} else {
  std::cout << "dynamic_cast failed!" << std::endl;
}

如果参数类型不是多态的,则不能将dynamic_cast强制转换用于向下强制转换(强制转换为派生类)。例如:

代码语言:javascript复制
Base *base = new Base;
Derived* d = dynamic_cast<Derived*>(base);

这将会转换失败。

3.3 const_cast

const_cast主要用于在变量中添加或删除const限定符。当你需要修改对象的const性,允许对先前的const对象进行非const访问时,它特别有用。

例如:

代码语言:javascript复制
const int c = 42;
int& c1 = const_cast<int&>(c);

3.4 reinterpret_cast

reinterpret_cast主要用于将一种数据类型的指针转换为另一种数据类型的指针,即使转换前后的数据类型无关。它用于低级、不安全的转换,由于可能出现未定义的行为,因此应该非常谨慎地使用它。

例如:

代码语言:javascript复制
int i = 42;
char* c = reinterpret_cast<char*>(&i);

好了,本节把类型转换全部梳理了一遍,相信看完会有所收获,就先到这里了~

0 人点赞