C++四种类型转换

C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:

TYPE b = (TYPE)a   

C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。

     static_cast                 静态类型转换。如int转换成char

                  reinterpreter_cast  重新解释类型

            dynamic_cast            命名上理解是动态类型转换。如子类和父类之间的多态类型转换。

       const_cast,             字面上理解就是去const属性。

4种类型转换的格式:

         TYPE B = static_cast<TYPE> (a) 

 

一般性介绍

1)static_cast<>()   静态类型转换,编译的时c++编译器会做类型检查

基本类型能转换 但是不能转换指针类型

         2)若不同类型之间,进行强制类型转换,用reinterpret_cast<>() 进行重新解释

         3)一般性结论:

C语言中  能隐式类型转换的,在c++中可用 static_cast<>()进行类型转换。因C++编译器在编译检查一般都能通过;

C语言中不能隐式类型转换的,在c++中可以用 reinterpret_cast<>() 进行强行类型 解释。总结:static_cast<>()和reinterpret_cast<>() 基本上把C语言中的 强制类型转换给覆盖

reinterpret_cast<>()很难保证移植性。

         4)dynamic_cast<>(),动态类型转换,安全的基类和子类之间转换;运行时类型检查

         5)const_cast<>(),去除变量的只读属性

典型案例

static_cast和reinterpreter_cast
#include <iostream>
using  namespace std;

int main()
{
    double dpi = 3.1415926;

    int num1 = (int)dpi;  // c类型转换
    int num2 = static_cast<int> (dpi); // c++静态类型转换, 编译时编译器会进行类型检查
    int num3 = dpi;      // c语言中,隐士类型转换的地方,去可以使用,有警告,但是加上Static_cast就没了

    // char* ===> int*
    char *p1 = "hello world";
    int  *p2 = NULL;

    // p2 = static_cast<int*>(p1);  // 编译器会进行类型检查,有错就提示出来

    p2 = reinterpret_cast<int*> (p1);

    cout << "p1 = " << p1 <<endl;  //%s 一个字符串,如果是*p1就是h
    cout << "p2 = " << p2 << endl; //%d 字符串的首地址

    // 总结:通过reinterpreter_cast<>(),static_cast<>(),把c语言中的强制类型都覆盖了
    return 0;

}

//结果
//p1 = hello world
//p2 = 0x47f048

 

dynamic_cast用法和reinterpret_cast用法

#include <iostream>
using  namespace std;

/*
    C分格的强制类型转换(Type cast),很简单,不管什么类型,都是
    Type b = (Type)a;

    C++风格提供了4种类型转换操作符,来对应不同的场合的应用
        static_cast    静态类型转换,如int转换成char
        reinterpreter_cast  重新解释类型
        dynamic_cast       命名上理解动态类型转换,如子类和父类之间的多态类型转换
        const_cast     字面理解就是const属性

        4中类型转换格式:
        Type b = static_cast<Type> (a);
*/
class Animal
{
public:
    virtual void cry() = 0;
};

class Dog : public Animal
{
public:
    virtual void cry()  // 虚函数重写
    {
        cout <<"\t汪汪" << endl;
    }
    void doHome()
    {
        cout << "\t看家" << endl;
    }
};

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

// 对象唱戏,发生多态, 只能用指针或者引用
void playObj(Animal &base)
{
    base.cry(); // 1有继承, 2 虚函数重写,3父类指针(引用) 指向子类对象 ===> 发生多态
    cout << endl;

    // 需求:识别子类对象
    // dynamic_cast 运行时类型识别

    Dog *pDog = dynamic_cast<Dog *> (&base);
    if (pDog != NULL)
    {
        pDog->doHome();  // 做自己特有的工作
    }

    cout << endl;

    Cat *c1 = dynamic_cast<Cat *> (&base);  // 父类对象 ==> 子类对象
                                           // 向下转型
                                          // 把老子转成小子
    if (c1 != NULL)
    {
        c1->doThing();
    }

}
class Tree{};
int main()
{
    Dog d1;
    Cat c1;

    Animal *pBase = NULL;
    pBase = &d1;
    pBase = static_cast<Animal*>(&d1); // c++编译时,进行类型检查,将d1指针转换成父类指针

    // 强制类型转换
    pBase = reinterpret_cast<Animal*>(&d1);

    {
        Tree t1;
        // 将树指针 转换成动物类指针
//        pBase = static_cast<Animal*>      (&t1);  // c++编译器,类型检查 不通过
        pBase = reinterpret_cast<Animal*> (&t1); // 可以 重新解释。。。。强制类型转换的味道

    }
    playObj(d1);
    playObj(c1);
    return 0;
}

//结果
// 汪汪
//
// 看家
//
// 喵喵
//
//
// 抓老鼠

 

 const_cast用法

// const char*p,中得const表示 p指向的内存空间 不可以修改 就是*p(值)不能改
void printBuf(const char*p)
{
//     p[0] = 't';  报错

    char *p1 = NULL;

    // 程序员要清楚地知道:变量转换前,和转换后的类型
    p1 = const_cast<char*>(p);   // 将p 由const char* == > char*
    cout << "p = " << p << endl;

    p1[1] = 't';  // 通过p1修改了 p指向的内存空间

    // 转换后 可以间接修改p的值,不准换的话,也不能间接修改
    cout << "p = " << p << endl;

}

int main()
{
     char buf[] = "aaaaa";
    // 程序员 要确保 p所指向的内存空间,确实能修改,如果不能修改,会带来灾难性的后果
     printBuf(buf);

//    char *myBuf = "bbbbbbbb";  // 常量,不能修改
//    printBuf(myBuf);
    return 0;
}

 

 

 

 

posted @ 2020-02-28 12:47  Lucky&  阅读(1684)  评论(1编辑  收藏  举报
//返回顶部开始
//返回顶部结束