• C++类型转换


    C++提供了四种类型转换,static_cast , dynamic_cast , const_cast , reinterpret_cast .而在C语言里有(),这种C风格的转换在C++里同样适用,但是强烈建议使用C++这四种转换。因为他们更安全,在语法上更优秀。

    1. const_cast

        他是这四种里唯一可以舍弃常量特性的类型转换,从理论上来说讲是没有必要将const转换为非const类型的。但是在有些时候每个函数需要采用const变量,但是必须将这个const变量传给非const参数的函数。

      

        void changeChar(char * p)
        {
            p = "word";
        } 
        
        void f(const char * p)
        {
            changeChar(const_cast<char*>(p));
        }
    int main(int argc, char** argv)
    {    char * p = "a";
    //    changeChar(p);
        f(p);
        std::cout << *p << std::endl;
         
        return 0;
    }

    结果是 a;

      2.static_cast

      最常用的就是类继承中的向下传递,

      

    class base
    {
        public:
            base();
             void print(){
                std::cout << "base" << std::endl;
            }    
        virtual ~base();
    };
    
    class drivate : public base
    {
        public:
            drivate();
             void print()
            {
                std::cout << "drivate" << std::endl;
            }
            virtual ~drivate();    
    };
    int main(int argc, char** argv)
    {    base *Base;
        drivate *Drivate;
        Base = Drivate;  //go up
        Base->print();
        
        base *Base1;
        drivate *Drivate1;
        Drivate1 = static_cast<drivate*>(Base1); //go down
        Drivate1->print();
         
        return 0;
    }

    向上传递在C++中很正常,也就是基类指向了派生类。但是想下传递就需要我们static_cast来转化了。这样做的安全性会降低,因为他不会再运行期间执行类型检测

    static_cast不是万能的,比如:无法将指针转化为不相关的其他类型的指针,无法将某种类型的对象直接转化为另一种类型的对象,无法讲const类型转化为non-const类型的。不能将int转化为指针等等,凡是C++认为无意义的转化,static_cast都无法实现

      3.reinterpret_cast

      reinterpret_cast比staic_cast功能强大,但是意味着reinterpret_cast的安全性要更差。

      他可以支持技术上在C++不被类型规则允许,但在某些情况下程序员有必须的类型转化,例如将一个引用转化为和他无关的类型的引用,也可以将一个指针转化为和他不相关的指针类型,即使这两种指针类型无任何继承关系,这个关键字经常将指针转化为void*类型,或则将void*指针转化为其他类型的指针。

      

    class A
    {
        public:
            void print(){
                std::cout << "AAA" << std::endl;
            }
    };
    class B
    {
        public:
            void print(){
                std::cout << "BBB" << std::endl;
            }
    }; 
    
    int main(int argc, char** argv)
    {    A a;
        B b;
        A *aPtr = &a;
        B *bPtr = &b;
        
        aPtr = reinterpret_cast<A*>(bPtr);
        aPtr->print();
        
        //void *p = aPtr;
        //aPtr = reinterpret_cast<A*>(p);
        
        void* p = reinterpret_cast<void*>(aPtr);
        A& aRef = a;
        B& bRef = reinterpret_cast<B&>(a);
        bRef.print();
        
        return 0;
    }

    使用reinterpret_cast一定要十分的小心;因为在执行的时候不会执行任何类型检测;

      4.dynamic_cast

      dynamic_cast为继承层次结构内的类型转换提供运行时检测,可用他来转换指针或则引用,重要的是dynamic_cast在运行时检测底层对象的类型信息,如果转化的没有意义,dynamic_cast会返回一个空指针或则抛出个异常std::bad_cast;

      注意在运行检测时候类型信息储存在虚表里,所以这个对象至少有一个虚方法,如果没有虚方法则在编译的时候就会报错,异常;

      

      dynamic_cast < type-id > ( expression )

      该运算符把expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void*;

      

    class Base
    {
        public:
        Base();
        virtual void print(){
                std::cout << "Base" << std::endl;
            }
        virtual ~Base();    
    };
    
    class Derived : public Base
    {
        public:
        Derived();
        virtual void print(){
                std::cout << "Derived" << std::endl;
            }
        virtual ~Derived();    
    };
    
    int main(int argc, char** argv)
    {     Base * base;
         Derived * derived ;
         //base = derived;        //work
         dynamic_cast<Derived *>(base);
         base->print();
         
         
        return 0;
    }

     

      

      

        

  • 相关阅读:
    postman环境和全局变量设置语句
    2016 GitHub章鱼猫观察报告之开源统计
    Multiload-ng
    忠告初学者学习Linux系统的8点建议
    真有用?Snap和Flatpak 通吃所有发行版的打包方式。
    教你如何在Kali Linux 环境下设置蜜罐?
    下一代GNU/Linux显示服务Wayland 1.12正式发布
    为 Github 创造 Integration
    简单易懂的crontab设置工具集
    爆料喽!!!开源日志库Logger的剖析分析
  • 原文地址:https://www.cnblogs.com/boost/p/10352824.html
Copyright © 2020-2023  润新知