C++下的强制转换类型

一、static_cast

   static_cast,静态类型转换。

     下面,我举几个例子,大家就能清楚了。

int main(int argc, char const *argv[])
{
    char c = 'o';
    int a = (int)c;//相当于把c的acsill码赋值给了a

    double d = 3.1231231;
    int b = (int)d; 

    //上述两种转换都是C风格
    //下面看看C++风格的类型转换
    
    char c = 'o';
    int a = static_cast<int>c;

    double d = 3.1231231;
    int b = static_cast(int)d; 

    return 0;
}

  这种类型转换检查在编译期间完成的。如果强制转换在C中不能通过编译的,在C++中也不能通过编译。

char* s = “string”;
int* p = NULL;

p = s;//这里在c语言中编译不能通过
p = static_cast<int>s;//当然在C++中也不能编译通过

  所以,总结一句话就是:凡是在C语言中能够进行隐式转换的,都能用static_cast进行转换

   在C语言中,如果你想将上面的char* 转换为int* 还真没有什么办法。但是在C++中,提供了下面一个关键字,能够解决问题。

二、reinterpreter_cast

  reinterpreter_cast,重新解释类型

  现在,我们来看看上面不能进行转化的案例:

char* s = “string”;
int* p = NULL;

p = s;
p = reinterpreter_cast<int>s;

cout<<"p"<<p; //打印出s的地址

  当然,这个还可以這么玩:

#include<iostream>
using namespace std;


class Tree {};

class Animal{
public:
    virtual void cry() = 0;
};

class Dog : public Animal{
public:
    virtual void cry(){
        cout << "汪汪" << endl;
    }

};

class Cat : public Animal{
public:
    virtual void cry(){
        cout << "喵喵" << endl;
    }
};

void main(){
    Dog d1;
    Cat c1;

    Animal *pBase = NULL;

    pBase = &d1;

    pBase = static_cast<Animal *>(&d1); //让C++编译在编译的时候进行 类型检查 

    //强制类型转换 
    pBase = reinterpret_cast<Animal *>(&d1); 
    
    {
        Tree t1;
        //pBase = static_cast<Animal *>(&t1); // C++编译器会做类型检查
        pBase = reinterpret_cast<Animal *>(&t1);  //reinterpret_cast 重新解释 ....强制类转换的味道
    }
    system("pause");
}

  总结之,reinterpreter_cast是一种强制类型转换的语法规则。

  通过 reinterpret_cast<>() 和 static_cast<>()把C语言的强制类型转换 都覆盖了。

三、dynamic_cast

  dynamic_cast,动态类型转换

  下面,我通过一段代码来看看,这个类型转换有什么用途:

class Animal{
public:
    virtual void cry() = 0;
};

class Dog : public Animal{
public:
    virtual void cry(){cout << "汪汪" << endl;}
    void doHome(){cout << "看家" << endl;}
};

class Cat : public Animal{
public:
    virtual void cry(){cout << "喵喵" << endl;}
    void doThing(){cout << "抓老鼠" << endl;}
};


void playObj(Animal *base){base->cry(); // 1有继承 2虚函数重写 3 父类指针 指向子类对象  发生多态}

void main(){
    Dog d1;
    Cat c1;

    Animal *pBase = NULL;
    pBase = &d1;

    pBase = static_cast<Animal *>(&d1); //让C++编译在编译的时候进行 类型检查 
    pBase = reinterpret_cast<Animal *>(&d1); //强制类型转换 

    playObj(&d1);
    playObj(&c1);

    system("pause");
}

  我们知道,在playObj那里会发生多态,根据传来的不同类的对象,动态的调用属于自己的cry()函数。

  但是,我们现在想要这样需求:当传来的是Dog类对象,调用Dog类的doHome()方法;当传来的是Cat类的对象,调用Cat类的doThing()方法。现在,我们只知道在playObj()函数中会发生多态,动态判断传来的对象。想完成上述功能,就得利用C++提供的dynamic_cast()来动态解析传来的对象。

  下面,我们修改一下playOjb()函数,让其能够完成上述功能。

void playObj(Animal *base)
{
    base->cry(); // 1有继承 2虚函数重写 3 父类指针 指向子类对象  ==>多态// dynamic_cast 运行时类型识别  
    Dog *pDog = dynamic_cast<Dog *>(base);//动态地将基类指针转换为不同类的对象
    if (pDog != NULL){
        pDog->doHome(); 
    }
    Cat *pCat = dynamic_cast<Cat *>(base);    //父类对象 ===> 子类对象                   
    if (pCat != NULL){
        pCat->doThing();  
    }
}

  总结,dynamic_cast()主要完成的是,子类与父类之间类型的转换。

四、const_cast

  const_cast,常量类型转换

  简言之,取出const变量的只读属性

void printBuf(const char *  p){
    //p[0] = 'Z'; 不能完成修改
    char *p1 = NULL;//const char * ===> char * //把只读属性 去掉
    p1 = const_cast<char *>(p);

    p1[0] = 'Z' ;  //通过p1 去修改了内存空间
    cout << p << endl;
}

void main(){
    char buf[] = "aaaaaaaaafffffddd";
    char *myp = "aaaaaaaaafffffddd";

    //程序员 要确保 p所指向的内存空间 确实能修改 ;如果不能修改会带来灾难性后果
    //printBuf (buf); 数据存放在常量区,不能完成修改

    printBuf (myp);
    system("pause");
}

 

posted @ 2017-09-18 10:59  看雪。  阅读(290)  评论(0编辑  收藏  举报