C++中的类型转换

 1. C语言与C++类型转换的区别

(1)C语言中的类型转换

1.转换太过随意,可以在任意类型之间转换。

2.C风格的转换没有统一的关键字和标示符。对于大型系统,做代码排查时容易遗漏和忽略。

(2)C++为了解决了上面两个问题。

1.对类型转换做了细分,提供了四种不同类型转换,以支持不同需求的转换;

2.类型转换有了统一的标示符,利于代码排查和检视。

下面分别来介绍这四种转换:static_cast、dynamic_cast、const_cast和reinterpre_cast.

 1.1 static_cast强制类型转换

(1) 基本用法:static_cast<type-id> expression

(2) 用于基本类型间的转换,但是不能用于基本类型指针之间的转换

(3)用于类层次结构中基类和派生类之间指针或引用的转换

  上行转换(派生类---->基类)是安全的;

  下行转换(基类---->派生类)由于没有动态类型检查,所以是不安全的。

因为static_cast在编译期间转换的,无法在运行时检测类型,所以类型之间的转换可能存在风险

(4) 把任何类型的表达式转为void类型

(5) 使用特点

 a、主要执行非多态的转换操作,用于代替C中通常的转换操作

 b、隐式转换都建议使用static_cast进行标明和替换

#include <iostream>
using namespace std;
class Parent
{
​
};
class Child :public Parent
{
​
};
int main(void)
{
    int a = 1;
    char ch = 'x';
    a = static_cast<int>(ch);  //用于普通类型之间的转换
    //int *p = static_cast<int *>(&ch);
​
    Parent p;
    Child c;
    //p = c;
    p = static_cast<Parent>(c);  //用于有继承关系的类对象之间的转换
​
    //c = static_cast<Child>(p);
    Parent *p1 = static_cast<Parent *>(&c);   //类对象指针之间的转换
​
}

1.2 reinterpret_cast

1.基本用法:reinterpret_cast<type-id> expression

2.使用场景:

(1) 用于普通指针和引用之间的转换 (任意转换,不安全)

(2) 用于数字和指针之间的转换 (很容易造成野指针)

3.使用特点:比较危险,一般不推荐使用

#include <iostream>
using namespace std;
int main(void)
{
    int c = 200;
    int b = 100;
    char *p = reinterpret_cast<char *>(&c);  //用于普通指针之间的转换(不安全)
    cout << *(p + 1) << endl;
    //cout << *(&b + 1) << endl;
​
    int *q = reinterpret_cast<int *>(100); //用于数字和指针之间的转换(很容易出现野指针)
    *q = 1;
    return 0;
}

 1.3 const_cast

1.基本用法:const_cast<type-id>expression  注:type-id只能是指针或者引用,或是指向对象类型成员的指针

2.使用场景:

  (1) 常量指针转换为非常量指针,并且仍然指向原来的对象

  (2) 常量引用被转换为非常量引用,并且仍然指向原来的对象

3.使用特点:

  (1) cosnt_cast是四种类型转换符中唯一可以对常量进行操作的转换符

  (2) 去除常量性是一个危险的动作,尽量避免使用。     

c++中被const修饰的变量会被放在符号表里面,是一个真正的常量,如果对该常量取地址,则会在栈区重新

开辟一段新的空间,与之前符号标的常量无关

#include<iostream>
using namespace std;
int main(void)
{
    const int a=1;//常量
    int *p=const_cast<int*>(&a);  //如果对该常量取地址,则会在栈区重新开辟一段新的空间,与之前符号标中的常量无关
    *p=100;
    cout<<a<<endl;
    cout<<*p<<endl;     

    const int &m=1;
    int &n=const_cast<int &>(m);   //去const化
    n=100;
    cout<<"m="<<m<<endl;
    cout<<"n= "<<n<<endl; 
   

    const int x=1;
    int &y=const_cast<int&>(x);  //非指针,引用类型,不改变原常量
    y=222;
    cout<<"x="<<x<<endl;
    cout<<"y= "<<y<<endl; 

    int z=200;
    const int*p1=&z;
    int *q=const_cast<int*>(p1);  //指针类型去const化
    *q=999;
    cout<<"*p1="<<*p1<<endl;
    cout<<"*q="<<*q<<endl; 
    
    return 0;
}
//c++中被const修饰的变量会被放在符号表里面,是一个真正的常量,存放在常量区,如果对该常量取地址,则会在栈区重新
 // 开辟一段新的空间,与之前符号标的常量无关

1.4 dynamic_cast

1.基本用法:dynamic_cast<type-id> expression

2.使用场景:只有在派生类之间转换时才使用dynamic_cast,type-id必须是类指针,类引用或者void*。

3.使用特点:

 (1) 基类必须要有虚函数,因为dynamic_cast是运行时类型检查,需要运行时类型信息,而这个信息是存储在类的虚函数表             中,只有一个类定义了虚函数,才会有虚函数表(如果一个类没有虚函数,那么一般意义上,这个类的设计者也不想                 它成 为一个基类)。

   (2) 对于下行转换,dynamic_cast是安全的(当类型不一致时,转换过来的是空指针),而static_cast是不安全的(当类型不          一致时,转换过来的是错误意义的指针,可能造成踩内存,非法访问等各种问题)

   (3)  dynamic_cast还可以进行交叉转换

 

#include <iostream>
using namespace std;
class Parent
{
public:
    virtual void f()
    {
​
    }
};
class Child :public Parent
{
public:
    void f()
    {
​
    }
};
int main(void)
{
    Child *c = new Child;
    delete c;
    //c = static_cast<Child *>(new Parent); //派生类指针指向基类对象(错误)
    c = dynamic_cast<Child *>(new Parent);  //运行时候会进行类型检查,不能转换,会返回NULL,比static_cast安全
    if (NULL == c)
    {
        cout << "转换失败" << endl;
    }
    else
    {
        cout << "转换成功" << endl;
        delete c;
    }
​
    return 0;
    
}

总结:

1. 去const属性用const_cast。

2. 基本类型转换用static_cast。

3. 多态类之间的类型转换用daynamic_cast。

4. 不同类型的指针类型转换用reinterpret_cast。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

李 同学

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

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

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

打赏作者

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

抵扣说明:

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

余额充值