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;
}

 

 

  

  

    

 

上一篇:C++提供的四种新式转换--const_cast dynamic_cast reinterpret_cast static_cast


下一篇:Python基础学习(一)Python安装