C++ 类型转换

1. 隐式类型转换

  • 不同类型数据之间的运算
int i = 'C';
  • 函数调用时, 不同类型实参到形参的传值
void func(int i)
{
	...
}
func('C');

  • 函数定义时, return不同类型的数据
int func(void) {
	return 'C'; //需要先把'C'转换成整型数才能完成返回值的带回
}

2. 强制类型转换

  • C风格的强制转换
    • (目标类型)源类型变量
  • C++ 风格的强制类型转换
    • 目标类型(源类型变量)
  • 强制转换的优缺点
    • 优点: 语法形式简单, 转换功能强大
    • 缺点: 暴力转换, 很多不合理的转换也可以转换成功, 使用起来比较危险!

3. C++扩展的显示类型转换

目的就是为例替换掉强制类型转换, 可以在一定程度上把一些安全性和合理性的转换工作交给编译器来完成, 使用起来更加安全

3.1 静态类型转换

  • 比较适合判断转换合理性
  • 目标类型变量 = static_cast<目标类型> (源类型变量);
  • 用于隐式转换的逆转换(假设从A类型到B类型可以直接隐式转换, 从B到A一定可以做显示的静态类型转换 ), 常用于将void*转换为其他类型的指针.
    • void* 在 C中叫空指针或者万能指针, 可以表示任意类型的地址, 但它并不能直接使用获取其目标数值, 必须要转换成相应类型的指针才能做*运算获取数据
  • 用于自定义类型的转换(向下造型, 讲继承时细讲)
#include <iostream>
using namespace std;
int main(void) 
{   
    
    int a = 10;
    int* pi = &a;
    int* p_val = NULL;
    char c;

    // 其他任何类型的指针 都可以 隐式转换 到 void* 类型. 
    void* pv = pi;
    // 但必须要从 void* 转换成整型指针(int*)才能做*运算获取数据
    // 这里要用显示类型转换, 因为 p_val = pv; 不行 (C++ 不允许void* 直接隐式转换成其他指针类型) 
    p_val = static_cast<int*>(pv); // 静态类型转换下, 类型转换合理, 编译不报错
    cout << *p_val <<endl;  //10
    // 一个指针一定是个32位的字节的编号, 给它强制类型转换到单字节的整数的char类型变量当中, 非常不合理
    // c = static_cast<char> (pi); //静态类型转换下, 类型转换非常不合理 这步编译一定报错
    return 0;
}

3.2 动态类型转换

3.3 常类型转换

  • 目标类型变量 = const_cast<目标类型> (源类型变量);
  • 用于去除指针或引用的常属性, 即去除指针或者引用的底层const
#include <iostream>
using namespace std;
int main(void) 
{   
    int ci = 100;
    const int* pci = &ci;
    // *pci = 10000; // 编译报错
    //const_cast 把 pci 的底层const属性去掉,就可以通过 *pci_2 来修改ci了
    int *pci_2 = const_cast<int*>(pci);  
    *pci_2 = 10000;
    cout << ci << endl;
}

类似的还要:

#include <iostream>
using namespace std;
int main(void) 
{   
    string str = "xuehui";
    const string *p_str = &str;
    // *ps = "111";
    string *cp_str = const_cast<string *>(p_str);
    *cp_str= "111";
    cout << str << endl;
}

3.4 重解释类型转换

  • 把原有类型重新解释成其他的类型
  • 目标类型变量 = reinterpret_cast<目标类型> (源类型变量);
  • 用于任意类型指针或引用之间的转换, 一个指针的类型可以决定对内存的访问范围, 一个char* 只能访问一个字节内存(内存管理的基本单位是字节), 转为int* 以后就能访问4个字节内存. 重解释和强制转换差不多 ,用重解释好在可以在不确定转换是否合理时, 使得代码更加安全.
  • 可以实现指针和整型数之间的转换(地址编号转换成指针类型可以直接操作地址)
#include <iostream>
using namespace std;
int main(void) 
{   
    // 下面是 用 重解释类型 让两个不同类型指针之间转换
    // "\000" -> '\0' -> 0(字符常量) 三个意思一样, 字符串的结束标志
    char buf[] = "0001\00012345678\000123456";
    struct T {
        char type[5];
        char acc[9];
        char passwd[7];
    };
    // T* pt = buf; // buf是char*, 和 T* 是两个不相关的类型, 这样写编译报错
    T* pt = reinterpret_cast<T*>(buf);
    //  强制类型转换也可以 T* pt = (T*)buf; 重解释和强制类型转换差不多但更安全
    cout << pt->type << endl; //0001
    cout << pt->acc << endl; //12345678
    cout << pt->passwd <<endl; // 123456

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值