C和C++的类型转换

C语言传统的类型转换

C方式的类型转换方式:(Type) (Expression)Type (Expression),后者比较古老。C风格的强制类型转换容易出问题,比较粗暴,如:

typedef void(PF)(int);
struct Point {
    int x; int y;
};
int v = 0x12345;
PF* pf = (PF*)v;    //转换方式过于粗暴,试问:能否保证变量v作为地址是否一定指向PF*类型的函数入口
char c = char(v);   //char类型的数据取值范围有限,能否保证整型数v按照char方式转换一定会在其值域中
Point* p = (Point*)v;   //同样,无法保证将v作为Point*类别的地址值,该地址值一定是一个Point结构体对象的地址

C方式强制类型转换存在的问题:

  • 过于粗暴——

    任意类型之间都可以进行转换,编译器很难判断其正确性

  • 难于定位——

    在源码中无法快速定位所有使用强制类型转换的语句

C++的新类型转换

C++将强制类型转换分为四种不同的类型,分别是static_castconst_castdynamic_castreinterpret_cast,其用法为xxx_cast<Type>(Expression)

static_cast

使用要点:

  • 用于基本类型之间的转换;(基本类型:int、float、double……)
  • 不能用于基本类型指针间的转换
  • 用于有继承关系类对象之间的转换和类指针之间的转换;

const_cast

使用要点:

  • 用于去除变量的只读属性;
  • 强制转换的目标类型必须是指针或引用;

reinterpret_cast

使用要点:

  • 用于指针类型间的强制转换;
  • 用于整数和指针类型间的强制转换;

dynamic_cast

使用要点:

  • 用于有继承关系的类指针间的转换;
  • 用于有交叉关系的类指针间的转换;
  • 具有类型检查的功能;
  • 需要虚函数的支持;

补充说明:

  • 使用dynamic_cast转换如果不成功,将得到空指针,成功将返回指向类对象的指针或引用;

  • dynamic_cast是运行时处理的,而其他三种都是编译时处理的;

  • 在类族中进行上行转换时,dynamic_cast和static_cast的效果是一样的,但在下行转换时,dynamic_cast具有类型检查功能,比static_cast更安全。

    • 上行转换:子类向父类转换(C++中的继承是全部接收,故父类的成员子类都具有,进行上行转换时一般不会有问题)

    • 下行转换:父类向子类转换;

    下行转换的成功与否与将要转换的类型有关,即「将要转换的类指针(或引用)所指向对象的实际类型」与「转换结果对象的类型」一定要相同,否则转换失败。

代码演示

#include <iostream>
using namespace std;
void static_cast_demo() {
    int i = 0x12345;
    char c = 'c';
    int* pi = &i;
    char* pc = &c;
    c = static_cast<char>(i);
    //pc = static_cast<char*>(pi); //Error,static_cast不能转换基本类型指针
    cout << "static_cast affect i to c:" << i << " to " << c << endl;
}
void const_cast_demo() {
    const int& j = 1;
    int& k = const_cast<int&>(j);

    const int x = 2;    //在C++中进入符号表,但仍按照C语言方式分配存储空间
    int& y = const_cast<int&>(x); //相当于将x的内存空间重新起了一个别名,别名的使用方式不在有只读属性限定
    //int z = const_cast<int>(x); //Error,const_cast只能用于指针或引用类型的转换
    k = 5;
    cout << "k=" << k << ",j=" << j << endl;
    y = 8;
    cout << "x=" << x << ",y=" << y << endl; //由于x进入符号表,则从符号表中取用的时候仍为最初的值,而y是从分配的空间中读取值的
    cout << "&x=" << &x << ",&y" << &y << endl;   
}
void reinterpret_cast_demo() {
    int i = 0; char c = 'c';
    int* pi = &i; char* pc = &c;
    pc = reinterpret_cast<char*>(pi); 
    cout << "pc:" << (void*)pc << endl;//int*到char*之间的指针类型转换,由于cout输出字符指针是当作字符串的,所以用void*告诉程序按指针方式输出
    pi = reinterpret_cast<int*>(&c);  
    cout << "pi:" << pi << endl;//不同指针类型之间的强制类型转换
    pi = reinterpret_cast<int*>(i);   //整数和指针之间的强制类型转换
    //c = reinterpret_cast<char>(i);  //不支持基本类型之间的转换
    cout << "pi<int to int*>:" << pi << endl;
}
int main() {
    static_cast_demo();
    const_cast_demo();
    reinterpret_cast_demo();
}

原文链接: https://www.cnblogs.com/coro/p/13205907.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C和C++的类型转换

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/360213

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 下午1:10
下一篇 2023年3月2日 下午1:10

相关推荐