C++|【C++】类型转换


文章目录

    • C语言中的类型转换
      • 隐式类型转换
      • 显示类型转换(强制类型转换)
    • C++强制类型转化
      • static_cast
      • reinterpret_cast
      • const_cast
      • dynamic_cast
    • explicit

C语言中的类型转换 C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化
C语言中总共有两种形式的类型转换:隐式类型转换显式类型转换
隐式类型转换
编译器在编译阶段自动进行,能转就转,不能转就编译失败
适用于相近的类型
void show(int i){ //参数的接收发生了隐式类型转换 std::cout << i << std::endl; } int main(){ double d = 1.1; show(d); return 0; }

显示类型转换(强制类型转换)
需要用户自己处理,通常用于不相近类型的转换
int main(){ int a = 0; int* p = &a; //将指针强制转化为int类型 int b = (int)p; }

C++强制类型转化 C语言的类型转化有很大的缺陷:
  • 隐式类型转换可能会因为整形提升或者数据截断导致精度的丢失
  • 隐式类型有时会被程序员忘记或者忽略,造成错误
  • 显式类型转换将所有情况混合在一起,代码不够清晰,如果出现错误不好查
C++为了加强类型转化的规范性和可视性,引入了四种命名的强制类型转换操作符:static_cast、reinterpret_cast、const_cast、dynamic_cast
static_cast
static_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相关的类型进行转换。(即对应C语言中的隐式类型转换
int main(){ double d = 1.1; //可以让隐式类型转化更加规范 int a = static_cast(d); std::cout << i; }

reinterpret_cast
reinterpret_cast是一种较为危险的类型转换,通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型,通常适用于指针、引用、以及整数之间的类型转换。对应C语言的强制类型转化
int main(){ int a = 998; int* p1 = &a; //这里的强制类型转化,是把int指向的空间强制转化成了double指向的空间 //所以p1以前读取四个字节内容,转换后p2可以读取八个字节内存,所以p1在转换后指向的内容发生了变化 double* p2 = reinterpret_cast(p1); std::cout << *p2 <::endl<< *p1; }

C++|【C++】类型转换
文章图片

const_cast
通常用于删除变量的const属性
int main(){ //const变量会被编译器优化放到寄存器,加上volatile防止编译器优化 volatile const int a = 2; int* p = const_cast(&a); *p = 3; std::cout << a << std::endl; std::cout << *p << std::endl; return 0; }

dynamic_cast
【C++|【C++】类型转换】将基类的指针或引用安全地转换成派生类的指针或引用
基类和派生类之间的转换分为两种
  • 向上转型:子类对象指针/引用->父类指针/引用(切片原生支持的)
  • 向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast转型是安全的)
dynamic_cast的向下转换``只支持继承中的多态类型,也就是父类之中必须包含虚函数
class A { public: virtual void f() = 0; }; class B : public A{ public: virtual void f() { cout << "f()::B" << endl; } void showB() { cout << "showB()::B" << endl; } }; int main() { A* pa = new B; //把基类指针强制转换为派生类指针 B* pb = dynamic_cast(pa); //转换时会做安全检查,如果不能成功转换就会返回0 if (pb) { pb->showB(); } return 0; }

  • dynamic_cast只能用于含有虚函数的类
  • dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0
explicit 在C++中,explicit关键字用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换
class A{ public: explicit A(int a){ cout << "A(int a)" << endl; } private: int _a; }; int main(){ A a1(1); // 隐式转换-> A tmp(1); A a2(tmp); A a2 = 1; }

C++|【C++】类型转换
文章图片

a2使用赋值进行初始化,其实是先把1隐式类型转换为一个临时对象,然后用临时对象对a2进行赋值
使用explicit关键字修饰构造函数,A就不会进行隐式类型转换

    推荐阅读