C++ 4种强制类型转换

Wesley13
• 阅读 839

C++的四种强制类型转换为:static_cast、const_cast、reinterpret_cast和dynamic_cast

类型转换的一般形式:cast-name (expression);

static_cast

任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast;

double slope = static_cast (j) / i;

注:
  顶层const:表示指针本身是个常量。如:int *const p;
  底层const:表示指针所指的对象是一个常量。如:int const *p;

const_cast

该运算符只能改变运算对象的底层const。

#include<iostream>    
using namespace std;
int main()  
{  
    const char *pc=" HDU";  
    char *p=const_cast<char *>(pc);  //正确,
  
    cout<<"hello"<<p<<endl;  
    return 0;  
}  

注:此处只能用const_cast,而不能用static_cast;

reinterpret_cast

通常为运算对象的位模式提供较低层次上的重新解释。
注:
  1、在指针之间转换,将一个类型的指针转换为另一个类型的指针,无关类型;
  2、将指针值转换为一个整型数,但不能用于非指针类型的转换。

dynamic_cast

只用于对象的指针和引用,不能用于内置的基本数据类型的强制转换。
使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过。
运行时类型识别,用于将基类的指针或引用安全地转换成派生类的指针或引用。

对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针;
对引用进行dynamic_cast,失败抛出一个异常bad_cast,成功返回正常cast后的对象引用。

对于“向上转换”(即派生类指针或引用类型转换为其基类类型),无论是指针还是引用向上转换都是安全地。
对于“向下转型”有两种情况:
  1、基类指针所指对象是派生类类型的,这种转换是安全的;
  2、基类指针所指对象为基类类型,在这种情况下dynamic_cast在运行时做检查,转换失败,返回结果为0;
  在引用上,dynamic_cast依旧是常用于“安全的向下转型”。与指针一样,引用的向下转型也可以分为两种情况,与指针不同的是,并不存在空引用,所以引用的dynamic_cast检测失败时会抛出一个bad_cast异常。

#include <iostream>
#include <cstring>
using namespace std;
class A
{
public:
    virtual void f()
    {
       cout << "hello" << endl;
    }
};
 
class B: public A
{
public:
    void f()
    {
        cout << "hello2" << endl;
    }
 
};

int main()
{
    A* a1=new B;//a1是A类型的指针指向一个B类型的对象
    A* a2=new A;//a2是A类型的指针指向一个A类型的对象
    B* b;
    
    b=dynamic_cast<B*>(a1);
    //结果为not null,向下转换成功,a1之前指向的就是B类型的对象,所以可以转换成B类型的指针。
    if(b==NULL)
        cout<<"null"<<endl;
    else
        cout<<"not null"<<endl;
    
    b=dynamic_cast<B*>(a2);//结果为null,向下转换失败
    if(b==NULL)
        cout<<"null"<<endl;
    else
        cout<<"not null"<<endl;
    return 0;
}

总结

  基本类型转换用static_cast。
  去const属性用const_cast。
  不同类型的指针类型转换用reinterpreter_cast。
  多态类之间的类型转换用daynamic_cast。

C++ 4种强制类型转换

C++的四种强制类型转换为:static_cast、const_cast、reinterpret_cast和dynamic_cast

类型转换的一般形式:cast-name (expression);

static_cast

任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast;

double slope = static_cast (j) / i;

注:
  顶层const:表示指针本身是个常量。如:int *const p;
  底层const:表示指针所指的对象是一个常量。如:int const *p;

const_cast

该运算符只能改变运算对象的底层const。

#include<iostream>    
using namespace std;
int main()  
{  
    const char *pc=" HDU";  
    char *p=const_cast<char *>(pc);  //正确,
  
    cout<<"hello"<<p<<endl;  
    return 0;  
}  

注:此处只能用const_cast,而不能用static_cast;

reinterpret_cast

通常为运算对象的位模式提供较低层次上的重新解释。
注:
  1、在指针之间转换,将一个类型的指针转换为另一个类型的指针,无关类型;
  2、将指针值转换为一个整型数,但不能用于非指针类型的转换。

dynamic_cast

只用于对象的指针和引用,不能用于内置的基本数据类型的强制转换。
使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过。
运行时类型识别,用于将基类的指针或引用安全地转换成派生类的指针或引用。

对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针;
对引用进行dynamic_cast,失败抛出一个异常bad_cast,成功返回正常cast后的对象引用。

对于“向上转换”(即派生类指针或引用类型转换为其基类类型),无论是指针还是引用向上转换都是安全地。
对于“向下转型”有两种情况:
  1、基类指针所指对象是派生类类型的,这种转换是安全的;
  2、基类指针所指对象为基类类型,在这种情况下dynamic_cast在运行时做检查,转换失败,返回结果为0;
  在引用上,dynamic_cast依旧是常用于“安全的向下转型”。与指针一样,引用的向下转型也可以分为两种情况,与指针不同的是,并不存在空引用,所以引用的dynamic_cast检测失败时会抛出一个bad_cast异常。

#include <iostream>
#include <cstring>
using namespace std;
class A
{
public:
    virtual void f()
    {
       cout << "hello" << endl;
    }
};
 
class B: public A
{
public:
    void f()
    {
        cout << "hello2" << endl;
    }
 
};

int main()
{
    A* a1=new B;//a1是A类型的指针指向一个B类型的对象
    A* a2=new A;//a2是A类型的指针指向一个A类型的对象
    B* b;
    
    b=dynamic_cast<B*>(a1);
    //结果为not null,向下转换成功,a1之前指向的就是B类型的对象,所以可以转换成B类型的指针。
    if(b==NULL)
        cout<<"null"<<endl;
    else
        cout<<"not null"<<endl;
    
    b=dynamic_cast<B*>(a2);//结果为null,向下转换失败
    if(b==NULL)
        cout<<"null"<<endl;
    else
        cout<<"not null"<<endl;
    return 0;
}

总结

  基本类型转换用static_cast。
  去const属性用const_cast。
  不同类型的指针类型转换用reinterpreter_cast。
  多态类之间的类型转换用daynamic_cast。

http://www.frankyang.cn/2017/05/10/c-4%E7%A7%8D%E5%BC%BA%E5%88%B6%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2/

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
happlyfox happlyfox
3年前
go好用的类型转换第三方组件
关于我通过学习和分享的过程,将自己工作中的问题和技术总结输出,希望菜鸟和老鸟都能通过自己的文章收获新的知识,并付诸实施。Cast介绍Cast是什么?Cast是一个库,以一致和简单的方式在不同的go类型之间转换。Cast提供了简单的函数,可以轻松地将数字转换为字符串,将接口转换为bool类型等等。当一个明显的转换是可能的时,Cast会智
happlyfox happlyfox
3年前
go好用的类型转换第三方组件 [cast]
关于我Cast介绍Cast是什么?Cast是一个库,以一致和简单的方式在不同的go类型之间转换。Cast提供了简单的函数,可以轻松地将数字转换为字符串,将接口转换为bool类型等等。当一个明显的转换是可能的时,Cast会智能地执行这一操作。它不会试图猜测你的意思,例如,你只能将一个字符串转换为int的字符串表示形式,例如“8”。Cast是为Hugo开发的
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
CAST()函数可以进行数据类型的转换。
CAST()函数可以进行数据类型的转换。CAST()函数的参数有两部分,源值和目标数据类型,中间用AS关键字分隔。以下例子均通过本人测试。一、转换列或值语法:cast(列名/值as数据类型)用例:1)、转换列\将empno的类型(number)转换为varchar2类型。selectcast(empnoasv
Easter79 Easter79
3年前
SQL中的cast()函数
CAST函数用于将某种数据类型的表达式显式转换为另一种数据类型。CAST()函数的参数是一个表达式,它包括用AS关键字分隔的源值和目标数据类型。一、语法:  CAST(expressionASdata\_type)  参数说明:  expression:任何有效的SQServer表达式。  AS
Stella981 Stella981
3年前
SQL中的cast()函数
CAST函数用于将某种数据类型的表达式显式转换为另一种数据类型。CAST()函数的参数是一个表达式,它包括用AS关键字分隔的源值和目标数据类型。一、语法:  CAST(expressionASdata\_type)  参数说明:  expression:任何有效的SQServer表达式。  AS
Wesley13 Wesley13
3年前
C++面试
C/C基础dynamic\_cast和static\_cast区别,为什么dynamic\_cast能做到类型检查new和malloc区别,new实际上执行了什么操作,可能在什么步骤出现异常虚继承的细节,纯虚函数智能指针的作用和实现,auto\_ptr和share\_ptr区别,循环引用,weak
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这