ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C++基础语法---四种cast操作符

2021-02-24 14:01:21  阅读:282  来源: 互联网

标签:const derived dynamic C++ --- cast base 指针


C++中四种类型转换是:static_cast, dynamic_cast, const_cast, reinterpret_cast

const_cast 

用于将const变量转为非const。const_cast中的类型必须是指针、引用或者指向对象类型成员的指针,主要是用来去掉const属性,当然也可以加上const属性。主要是用前者,后者很少用。核心:对地址的操作。

void const_cast_test()
{
    class A
    {
    public:
        A() : _num(0) {}

    public:
        int _num;
    };

    const int c_type = 100;
    //auto var = const_cast<int>(c_type); //非指针、引用,开发环境报错

    //类指针
    const A a;
    const A *pa = &a;
    //pa->_num = 10;    //开发环境报错
    A *pa2 = const_cast<A *>(pa);
    pa2->_num = 11;
    std::cout << "pa->_num=" << pa->_num << "; pa2->_num=" << pa2->_num << std::endl;
    //pa->_num=11; pa2->_num=11

    //基本数据类型
    const int i = 3;
    int *p = const_cast<int *>(&i);
    *p = 10; //success
    std::cout << "i=" << i << "; *p=" << *p << std::endl;
    //i=3; *p=10
    {
        volatile const int i = 3;
        int *p = const_cast<int *>(&i);
        *p = 10; //success
        std::cout << "second i=" << i << "; *p=" << *p << std::endl;
        //second i=10; *p=10
    }
    //加上const属性
    int j = 10;
    const int *k = const_cast<const int *>(&j); //一般可以直接写const int* k = &j;

    if(0)
    {
        //对于本身定义为const的类型,应用const_cast去掉了const属性,然后再对这块内容进行write操作时,程序崩溃
        const char* c_str = "hello world";
        char* sz = const_cast<char*>(c_str);
        sz[0] = 'H';
        std::cout << "c_str =" << c_str<< "; sz =" << sz << std::endl;
        //result---> Segmentation fault (core dumped)
    }
    
}

static_cast

是最常用的转换,但是转换的时候不会检查类型来保证转换的安全性,因此安全性相对其他转换较低。需要注意的是:static_cast不能转换掉expression的const、volitale、或者__unaligned属性。用于各种隐式转换,比如非const转const,void*转指针等, static_cast能用于多态向上转化,如果向下转能成功但是不安全,结果未知。static_cast本质上是  传统c语言强制转换的替代品。核心:c语言强制转换。

void static_cast_test()
{
    class base
    {
    };
    class derived : public base
    {
    };

    // 基本类型转换 float -> int
    int i;
    float f = 67.27f;
    i = static_cast<int>(f);

    //子类 -> 父类
    derived d;
    base b = static_cast<base>(d);

    //父类 -> 子类
    base bb;
    derived *dd = static_cast<derived *>(&bb); //compile error

    base *pB = new base;
    derived *pD = static_cast<derived *>(pB); //编译通过,但是是******不安全的******(例如访问子类成员)
}

reinterpret_cast

即为重新解释,此标识符的意思即为数据的二进制形式重新解释,但是不改变其值。T必须是一个指针、引用、算术类型、函数指针或者成员指针。操作符用于将一种类型转换为另一种不同的类型,比如可以把一个整型转换为一个指针,或把一个指针转换为一个整型,因此使用该操作符的危险性较高,一般不应使用该操作符。

void reinterpret_cast_test()
{
    class base
    {
    };
    class derived : public base
    {
    };

    class other
    {
    };

    //1.不同类型之间的转换
    //可以转,但是不安全
    base* b1 = new derived;
    other* o1 = reinterpret_cast<other*>(b1);//OK

    //2.算术类型转指针
    long l = 0;
    base* b2 = reinterpret_cast<base*>(l);//OK

    int i = 0;
    b2 = reinterpret_cast<base*>(i);//OK

    float f = 0.0;
    //b2 = reinterpret_cast<base*>(f); //无法将浮点型变量进行reinterpret转换

    char c = 'a';
    b2 = reinterpret_cast<base*>(c);//OK

    bool b = true;
    b2 = reinterpret_cast<base*>(b);//OK

    //3.指针转换为算术类型
    base* b3 = new derived;
    long l3 = reinterpret_cast<long>(b3);
}

dynamic_cast

一、简介:将一个基类对象指针(或引用)cast (抛)到继承类指针,dynamic_cast 会根据基类指针是否真正指向继承类指针来做相应处理。二、返回值:对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针;对引用进行dynamic_cast,失败抛出一个异常,成功返回正常cast后的对象引用。 三、注意:dynamic_cast在将父类cast到子类时,父类必须要有虚函数。即操作数中必须要有虚函数。四、原理:dynamic_cast<> 会用到RTTI技术。编译器都是通过vtable找到对象的RTTI信息的,如果基类没有虚方法,也就无法判断一个基类指针变量所指对象的真实类型。

void dynamic_cast_test()
{
    class base
    {
        public:
        virtual void print(){std::cout<<"base print"<<std::endl;}
    };
    class derived : public base
    {
        public:
        void print(){std::cout<<"derived print"<<std::endl;}
    };

    class other
    {
        public:
        virtual void print(){std::cout<<"other print"<<std::endl;}
    };

    //*************** 类无虚函数 ***************
    //基类 -> 子类
	base *pb0 = new base;
	//derived *pd0 = dynamic_cast<derived *>(pb0); //如果pb0无虚函数时,IDE检查出错, 操作数必须包含 虚函数

    //不同类型的转换
    //会转换失败
    other* o2 = new other;
    derived* pd2 = dynamic_cast<derived*>(o2);
    if(pd2 == nullptr){std::cout<<"pd2 == nullptr"<<std::endl;}

    //基类 -> 子类
	base *pb1 = new base;
	derived *pd1 = dynamic_cast<derived *>(pb1); //失败,pd1 = NULL
    if(pd1 == nullptr){std::cout<<"pd1 == nullptr"<<std::endl;}

    //子类 -> 子类
	base *pb3 = new derived;
	derived *pd3 = dynamic_cast<derived *>(pb3); //成功
    if(pd3 != nullptr){pd3->print();}

    //子类 -> 基类
	base *pb4 = new derived;
	base *pd4 = dynamic_cast<base *>(pb4);		 //成功
    if(pd4 != nullptr){pd4->print();}
}

 

标签:const,derived,dynamic,C++,---,cast,base,指针
来源: https://blog.csdn.net/weixin_36887247/article/details/109499936

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有