• C++中的显式类型转换


    一、学习总结

    1.C++中额外提供的类型转换有

    (1) reinterpret_cast:

    格式:reinterpret_cast<type-id> (expression)
    ①type-id必须是一个指针、引用、算术类型、函数指针或成员指针。
    ②可以把一个指针转换成一个整数,也可以把一个整数转换成指针。
    跟C风格的强制类型转换类似(相当于C中使用小括号进行的类型转换),没有安全性检测。
    eg:
    int *p = (int *)pstr;
    int *p = reinterpret_cast<int *>pstr;
    注意:reinterpret_cast只能进行类型转换,但是不能去掉const属性


    (2) const_cast

    格式:const_cast<type-id> (expression)
    ①const_cast用于去除原类型的const或volatile属性。除了const和volatile修饰之外type-id需要和expression的类型是一样的(也就是说只有去
    除const和volatile属性的功能)

    对于const的转换的作用应该只是去掉编译警告而已,例如:
    char *ptr = const_cast<char *>("hello world");
    ptr[1] = 'M'; //Segmentation fault (core dumped)

    (3) dynamic_cast

    格式:dynamic_cast<type-id> (expression)
    该运算符把expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void *;
    如果type-id是类指针类型,那么expression也必须是一个指针;如果type-id是一个引用,那么expression也必须是一个引用。

    ①用于多态场合,即:必须有虚函数。
    ②主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
    ③在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。

    注意:dynamic_cast只能用在具有虚函数的类里面
    原因:使用虚函数后类中会多出一个虚函数指针,指向虚函数表,虚函数表中不仅仅只有虚函数,还有那些类的信息,里面包含了继承关系,
    dynamic_cast依据这些信息进行类型转换。dynamic_cast这个函数根据虚函数指针找到虚函数表中的类信息,从而知道要转换的对象是不是属
    于某一个类的。因此动态类型转换只能用在具有虚函数的类里面。

    称为动态转换的原因:是在运行时决定的,比如父类指针作为参数接收子类对象。


    (4) static_cast

    格式:static_cast<type-id> (expression)
    该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。
    ①用于类层次结构中基类和子类之间指针或引用的转换。
    ②进行上行转换(把子类的指针或引用转换成基类表示)是安全的;
    ③进行下行转换(把基类指针或引用转换成子类指针或引用)时,由于没有动态类型检查,所以是不安全的。
    ④用于基本数据类型之间的转换,如把int转换成char,把int转换成enum:这种转换的安全性也要开发人员来保证。
    ⑤把void指针转换成目标类型的指针(不安全!!)
    ⑥把任何类型的表达式转换成void类型。
    注意:static_cast不能转换掉expression的const、volitale、或者__unaligned属性。

    称为静态转换的原因:编译器在编译期决定的。

    2.这些转换后面要跟一个()表明他们是函数,带有<type-id>表明他们是模板函数

    3.类之间的转换用于上下行转换,无关的类之间是不可以强制类型转换的。

    4.多态是指向谁的实例就调用谁的函数,例如Child的指针指向new出来的Parent的实例,通过Child类型的类指针调用的是Parent的成员函数(前提是虚函数)。

    5.类的指针通过类型可以直接调用成员函数,但是不可以直接操作成员变量。
    Person *p1 = NULL;
    p1->hello(); //这里是完全没有问题的!!!!
    p1->a = 10; //Segmentation fault (core dumped)

    二、Demo

    #include <iostream>
    
    using namespace std;
    
    
    class Human {
        int a;
    public:
        int b;
        virtual void eating() {
            cout << "use hands" << endl;
        }
    
        //this is an exception,return Human*/&Human*
        virtual Human* return_test_ptr() {
            return this;
        }
    
    };
    
    
    class English : public Human {
    
    public:
        int b;
        void eating() {
            cout << "use knifes" << endl;
        }
        English* return_test_ptr() {
            return this;
        }
        void descriptor() {
            cout << "I am a English woman" << endl;
        }
    };
    
    
    class Chinese : public Human {
    
    public:
        int b;
        void eating() {
            cout << "use chopsticks" << endl;
        }
    };
    
    
    void eating_test(Human *h) {
        English *pe = NULL;
    
        h->eating();
    
        if (pe = dynamic_cast<English *>(h)) { //转换成功返回非NULL
            cout << "English man" << endl;
            pe->descriptor();
        }
    
        if (dynamic_cast<Chinese *>(h)) { //转换失败返回NULL, 利用dynamic_cast的检查。
            cout << "Chinese man" << endl;
        }
    }
    
    
    int main() {
        Human *ph1 = new Human();
        Human *ph2 = new Human();
        Human *ph3 = new Human();
        Chinese *pc = new Chinese();
        English *pe = new English();
    
        cout << "---------test: reinterpret_cast---------" << endl;
        int *pa = reinterpret_cast<int *>(~0);
    
        cout << "---------test: const_cast---------------" << endl;
        char *ptr = const_cast<char *>("hello world");
    
        cout << "---------test: static_cast---------------" << endl;
        ph1 = static_cast<Human *>(pc); // Uplink convert
        //pe = static_cast<English *>(pc); // error
        pc = static_cast<Chinese *>(ph2); //Downlink conversion
        pc->eating();
    
        cout << "---------test: dynamic_cast-------------" << endl;
        eating_test(pe);
    
        return 0;
    }
    
    
    /*
    ---------test: reinterpret_cast---------
    ---------test: const_cast---------------
    ---------test: static_cast---------------
    use hands
    ---------test: dynamic_cast-------------
    use knifes
    English man
    I am a English woman
    */
  • 相关阅读:
    BZOJ_3159_决战
    11.19 ~ 11.25训练计划+总结
    BZOJ_1304_[CQOI2009]叶子的染色_树形DP
    BZOJ_1999_[Noip2007]Core树网的核_单调队列+树形DP
    BZOJ_4033_[HAOI2015]树上染色_树形DP
    BZOJ_5338_ [TJOI2018]xor_可持久化trie
    BZOJ_2957_楼房重建_线段树
    BZOJ_3124_[Sdoi2013]直径_树形DP
    BZOJ_4987_Tree_树形DP
    「JOISC 2019 Day2」两个天线(线段树)
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/10629404.html
Copyright © 2020-2023  润新知