C++ 类型转换

一、C 语言类型转换

1. 两种形式

  1. 隐式类型转换:编译器自动完成(相近类型)
  2. 显式强制类型转换(类型)变量 手动强转

2. 代码示例

int i = 1;
double d = i;                // 隐式转换

int* p = &i;
int address = (int)p;        // 显式强制转换

3. C 语言转换缺点

  1. 隐式转换可能出问题:精度丢失、数据截断
  2. 显式转换所有类型混用:代码不清晰、不安全
  3. 无法在继承体系中做安全检查:容易越界访问

二、C++ 强制类型转换(4 种关键字)

C++ 为了解决 C 语言类型转换的问题,提供 4 种命名转换,更规范、更安全。

关键字用途
static_cast静态转换,相近类型、编译器隐式转换
reinterpret_cast重解释类型,不相关类型、指针/整数转换
const_cast去掉/添加 const/volatile 属性
dynamic_cast继承体系中安全向下转型(必须含虚函数)

三、static_cast 静态转换

1. 作用

  • 用于相近类型转换
  • 编译器能隐式执行的转换都可以用它
  • 不能用于无关类型转换

2. 代码

double d = 12.34;
int a = static_cast<int>(d);   // 正确:相近类型

四、reinterpret_cast 重解释转换

1. 作用

  • 用于不相关类型之间的转换
  • 对二进制位重新解释
  • 常用于指针 ↔ 整数、不同类型指针转换

2. 代码

int a = 10;
int* p = reinterpret_cast<int*>(a);

五、const_cast 常量转换

1. 作用

  • 去掉 const 属性
  • 也可添加 const/volatile

2. 关键:volatile

  • const 变量会被编译器优化,直接从寄存器取值
  • volatile 告诉编译器:每次必须从内存读取,禁止优化

3. 代码

volatile const int n = 10;
int* p2 = const_cast<int*>(&n);
(*p2)++;
cout << n << endl;   // 输出 11

六、dynamic_cast 动态安全转换

1. 作用

继承体系中:父类指针 → 子类指针(安全向下转型)

2. 规则

  • 必须包含虚函数(运行时类型识别 RTTI)
  • 如果父指针真的指向子类 → 转换成功
  • 如果父指针指向父对象 → 转换失败,返回 nullptr

3. 代码示例

class AA
{
public:
    virtual void f() {}  // 必须有虚函数
    int _x = 0;
};

class BB : public AA
{
public:
    int _y = 0;
};

void fun(AA* pa)
{
    BB* pb = dynamic_cast<BB*>(pa);

    if (pb)
    {
        cout << "转换成功:指向子类" << endl;
    }
    else
    {
        cout << "转换失败:指向父类" << endl;
    }
}

4. 运行结果

转换失败:指向父类
转换成功:指向子类

七、自定义类型转换

1. 单参数构造函数隐式转换

class A
{
public:
    A(int a) :_a(a) {}
};

A a1 = 1;   // 隐式转换:int → A

2. 禁止隐式转换:explicit

explicit A(int a)

加了 explicit 后,A a1=1 编译报错。

3. 自定义类型之间转换

class B
{
public:
    B(const A& a) {}
};

A a1;
B b1 = a1;   // A → B

八、完整代码笔记版

#include<iostream>
#include <windows.h>
using namespace std;

// C 语言类型转换问题:
// 1. 隐式转换可能精度丢失
// 2. 显式转换代码不清晰、不安全

class A
{
public:
    A(int a) :_a(a) {}
private:
    int _a;
};

class B
{
public:
    B(const A& a) {}
private:
    int _a;
};

void test_1()
{
    int i = 1;
    double d = i;
    printf("%d, %.2f\n", i, d);

    int* p = &i;
    int address = (int)p;
    printf("%x, %d\n", p, address);

    A a1 = 1;
    B b1 = a1;

    volatile const int n = 10;
    int* p1 = (int*)&n;
    (*p1)++;
    cout << n << endl;
    cout << *p1 << endl;
}

// C++ 四种强制类型转换

// static_cast:相近类型、静态转换
// reinterpret_cast:不相关类型、重解释
// const_cast:修改const属性
// dynamic_cast:继承安全向下转型

void test_2()
{
    double d = 12.34;
    int a = static_cast<int>(d);
    cout << a << endl;

    int* p = reinterpret_cast<int*>(a);

    volatile const int n = 10;
    int* p2 = const_cast<int*>(&n);
}

// dynamic_cast 安全向下转型

class AA
{
public:
    virtual void f() {}
    int _x = 0;
};

class BB : public AA
{
public:
    int _y = 0;
};

void fun(AA* pa)
{
    BB* pb = dynamic_cast<BB*>(pa);

    if (pb)
    {
        cout << "传入子类 转换成功" << endl;
    }
    else
    {
        cout << "传入父类 转换失败" << endl;
    }
}

void test_3()
{
    AA aa;
    fun(&aa);

    BB bb;
    fun(&bb);
}

int main()
{
    SetConsoleOutputCP(CP_UTF8);
    test_3();
    return 0;
}

九、总结

  1. C++ 提供 4 种安全类型转换
  2. static_cast:相近类型
  3. reinterpret_cast:不相关类型
  4. const_cast:修改 const
  5. dynamic_cast:继承体系安全向下转型
  6. dynamic_cast 必须有虚函数,否则无法使用
  7. volatile 禁止编译器对 const 变量优化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hehelm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值