C++与C强转异同(下)

简介: C++与C强转异同(下)

C++与C强转异同(上)https://developer.aliyun.com/article/1429075

四种强转详解:

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

语法:

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

static_cast

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

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

#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
    int    ii = 3;
    long ll = ii;                     // 绝对安全,可以隐式转换,不会出现警告。
    double dd = 1.23;
    long ll1 = dd;                  // 可以隐式转换,但是,会出现可能丢失数据的警告。
    long ll2 = (long)dd;              // C风格:显式转换,不会出现警告。
    long ll3 = static_cast<long>(dd);    // C++风格:显式转换,不会出现警告。
    cout << "ll1=" << ll1 << ",ll2=" << ll2 << ",ll3=" << ll3 << endl;
}
用于指针之间的转换

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

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

#include <iostream>
using namespace std;
void func(void* ptr) {   // 其它类型指针 -> void *指针 -> 其它类型指针
   double* pp = static_cast<double*>(ptr);
}
int main(int argc, char* argv[])
{
    int ii = 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>
using namespace std;
int main(int argc, char* argv[])
{
  int num = 4;
  const int* 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>
using namespace std;
void func(void* ptr) {  
  long long ii = reinterpret_cast<long long>(ptr);
  cout << "ii=" << ii << endl;
}
int main(int argc, char* argv[])
{
  long long ii = 10;
  func(reinterpret_cast<void *>(ii));
}
输出:

4 4

完结撒花(注本文章部分采用慕课往的C++基础课的文档)

目录
相关文章
|
6月前
|
编译器 程序员 C++
C++与C强转异同(上)
C++与C强转异同
94 0
|
11月前
|
程序员 编译器 C语言
C++风格与C风格类型强转异同
C++风格的强转: C++强制类型转换 C风格的强制类型转换很容易理解,不管什么类型都可以直接进行转换,使用格式如下: 目标类型 b = (目标类型) a; C++也是支持C风格的强制类型转换,但是C风格的强制类型转换可能会带来一些隐患,出现一些难以察觉的问题,所以C++又推出了四种新的强制类型转换来替代C风格的强制类型转换,降低使用风险。 在C++中,新增了四个关键字static_cast、const_cast、reinterpret_cast和dynamic_cast,用于支持C++风格的强制类型转换。 C++风格的强制类型转换能更清晰的表明它们要干什么,程序员只要看一眼这样的代码,立即
111 0
|
6月前
|
算法 程序员 编译器
C++与C的对比:理解两者之间的异同与选择
C和C++是两种广泛使用的编程语言,都提供底层访问能力和指针操作,适合高效底层编程。C++是面向对象的,支持类和对象,提供异常处理、丰富的标准库和更强的类型系统;而C语言面向过程,无内置异常处理,标准库较简单,编译速度快。选择使用哪种语言应考虑项目需求、团队熟悉度和性能要求。C++常用于游戏开发、桌面应用和高性能场景;C则在系统级编程、嵌入式系统和性能敏感应用中占优。
|
6月前
|
存储 缓存 安全
【C/C++ 基础 数组容器比较】深入探究C++容器:数组、vector与array之间的异同
【C/C++ 基础 数组容器比较】深入探究C++容器:数组、vector与array之间的异同
137 0
|
编译器 C语言 C++
【四、const与this指针详解】详解C与C++中const的异同,类中的const
【四、const与this指针详解】详解C与C++中const的异同,类中的const
117 0
|
2天前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
15 2
|
8天前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
33 5
|
14天前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
46 4