类型转换

一、类型转换的名称和语法

  类型转换有 c 风格的,当然还有 c++风格的。c 风格的转换的格式很简单(TYPE) EXPRESSION,但是 c 风格的类型转换有不少的缺点,有的时候用 c 风格的转换是不合 适的,因为它可以在任意类型之间转换,比如你可以把一个指向const 对象的指针转换 成指向非 const 对象的指针,把一个指向基类对象的指针转换成指向一个派生类对象的 指针,这两种转换之间的差别是巨大的,但是传统的 c 语言风格的类型转换没有区分这 些。还有一个缺点就是,c 风格的转换不容易查找,他由一个括号加上一个标识符组成, 而这样的东西在 c++程序里一大堆。所以 c++为了克服这些缺点,引进了 4 新的类型转换操作符。

C语言的强制类型转换(Type Cast)

TYPE b = (TYPE)a

C++提供了4类类型转换,分别处理不同的场合应用

static_cast                        静态转换类型

reinterpret_cast             重新解释类型转换、

dynamic_cast                   子类和父类之间的多态类型转换

const_cast                        去掉const属性转换

二、转换方式

1.static_cast 静态类型转换

static_cast<目标类型> (标识符)

 

  所谓静态,即在编译器内即可决定其类型类型的转换,用的也是最多的一种。

  static_cast用于内置的数据类型,还有具有继承关系的指针或引用的转换。

 2.dynamic_cast 子类和父类之间的多态类型转换

dynamic_cast<目标类型> (标识符)

用于多态中的父子类之间的强制转化,并且只能由子类型转换成父类型。

 3.const_cast 增加或者去除变量的const属性

const_cast<目标类型>(标识符)//目标类类型只能是指针或引用。

4.reinterpret_cast 重新解释类型转换

reinterpret_cast<目标类型> (标识符)

  interpret 是解释的意思,reinterpret 即为重新解释,此标识符的意思即为数据的二进制形式重新解释,但是不改变其值。

代码:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

class Building{};
class Animal{};
class Cat:public Animal{};

//static_cast
void test1()
{
    //基础数据类型
    int a = 99;
    char c = static_cast<char>(a);

    //基础数据类型指针
    //int* p = NULL;
    //char* sp = static_cast<char*>(p);//error

    //对象指针
    //Building* building = NULL;
    //Animal* ani = static_cast<Animal*>(building);//error

    //转换具有继承关系的对象指针
    //父类指针转成子类指针
    Animal* ani = NULL;
    Cat* cat1 = static_cast<Cat*>(ani);
    //子类指针转成父类指针
    Cat* soncat = NULL;
    Animal* anifather = static_cast<Animal*>(soncat);

    Animal aniobj;
    Animal& aniref = aniobj;
    Cat& cat2 = static_cast<Cat&>(aniref);

    Cat catobj;
    Cat& catref = catobj;
    Animal& anifather2 = static_cast<Animal&>(catref);

    //结论:static_cast用于内置的数据类型,还有具有继承关系的指针或引用的转换。
}
//dynamic_cast 转换具有继承关系的指针或引用,在转换前会进行对象类型检查
void test2()
{
    //基础数据类型
    //int a = 10;
    //char c = dynamic_cast<char>(a);//error

    //非继承关系的指针
    //Animal* ani = NULL;
    //Building* building = dynamic_cast<Building*>(ani);//error

    //具有继承关系指针
    //Animal* ani = NULL;
    //Cat* cat = dynamic_cast<Cat*>(ani);//error
    //报错原因在于 dynamic_cast做类型安全检查,
    //父类指针可以转换成子类指针(从小到大),类型不安全

    Cat* cat = NULL;
    Animal* ani = dynamic_cast<Animal*>(cat);
    //子类指针可以转换成父类指针(从大到小),类型安全
    
    //结论:dynamic_cast只能转换具有继承关系的指针或引用,并且只能由子类型转换成基类型
}
//const_cast 指针、引用或者对象指针
void test3()
{
    //基础数据类型
    int a = 10;
    const int& b = a;
    int& c = const_cast<int&>(b);
    c = 20;//此时c可以进行修改

    cout << "a:" << a << endl;//a:20
    cout << "b:" << b << endl;//b:20
    cout << "c:" << c << endl;//c:20

    //看指针
    const int* p = NULL;
    int* p2 = const_cast<int*>(p);

    int* p3 = NULL;
    const int* p4 = const_cast<const int*>(p3);
    //const_cast作用:增加或者去除变量的const属性
}

//reinterpret_cast 强制类型转换
typedef void(*FUNC1)(int, int);
typedef int(*FUNC2)(int, char*);
void test4()
{
    //1.无关的指针类型都可以进行转换
    Building* building = NULL;
    Animal* ani = reinterpret_cast<Animal*>(building);

    //2.函数指针转换
    FUNC1 func1;
    FUNC2 func2 = reinterpret_cast<FUNC2>(func1);

}

int main(void)
{
    test1();
    test2();
    test3();
    test4();
    return 0;
}

结论

结论1.
程序员要清除的知道:要转的变量,类型转换前是什么类型,类型转换后是什么类型。转换后有什么后果。 结论2.
一般情况下,不建议进行类型转换。

 

posted @ 2018-11-22 11:54  悦悦的小屋  阅读(250)  评论(0编辑  收藏  举报