zoukankan      html  css  js  c++  java
  • 【C++基础 10】四种cast转换的区别

    简介

    (1)c风格的转换

    (T)expression;
    (2)c++风格的四种转换

    static_cast<T>(expression);
    dynamic_cast<T>(expression);
    reinterpret_cast<T>(expression);
    const_cast<T>(expression);

    1. c风格转换

    int a = 1;
    double d = (double)a;//c风格转换

    一般许多书本会建议使用c++提供的四种类型转换而不是使用c风格的转换。
    因为c风格的类型转换有不少的缺点,它可以在任意类型之间转换,比如你可以把一个指向const对象的指针转换成指向非const对象的指针,把一个指向基类对象的指针转换成指向一个派生类对象的指针,这两种转换之间的差别是巨大的,但是传统的c语言风格的类型转换没有区分这些。还有一个缺点就是,c风格的转换不容易查找,他由一个括号加上一个标识符组成,而这样的东西在c++程序里一大堆。所以c++为了克服这些缺点,引进了4种新的类型转换操作符。

    2. static_cast静态转换

    static_cast<T>(expression);

    最常用的转换,但是转换的时候不会检查类型来保证转换的安全性

    class Base{ 
    	//.....
    };
    class Derived : public Base{
    	//.....
    };
    
    void main()
    {
    	//基本类型转换 float -> int
    	int i;
    	float f = 166.7f;
    	i = static_cast<int>(f);
    	//子类 -> 父类
    	Derived d;
    	Base b = static_cast<Base>(d);
    	
    	//父类 -> 子类
    	Base bb ;
    //	Derived* dd = static_cast<Derived>(bb);  //compile error
    	Base* pB = new Base;
    	Derived* pD = static_cast<Derived*>(pB); //编译通过,但是是不安全的(例如访问子类成员)
    }
    static_cast本质上是传统c语言强制转换的替代品。

    需要注意的是:static_cast不能转换掉expression的const、volitale、或者__unaligned属性。

    3. dynamic_cast动态转换

    dynamic_cast<T>(expression);

    该运算符把expression转换成T类型的对象。

    dynamic_cast转换操作符在执行类型转换时首先将检查能否成功转换,如果能成功转换则转换之,如果转换失败,如果是指针则反回一个0值,如果是转换的是引用,则抛出一个bad_cast异常,所以在使用dynamic_cast转换之间最好使用if语句对其转换成功与否进行测试。

    注意:

    (1)T必须是类的指针、类的引用或者void *。如果T是类指针类型,那么expression也必须是一个指针,如果T是一个引用,那么expression也必须是一个引用。

    (2)dynamic_cast转换符只能用于含有虚函数的类。

    class Base
    {
    public:
    	virtual void foo(){};
    };
    
    class Derived : public Base
    {
    
    };
    
    void main()
    {
    	//基类 -> 子类
    	Base *pb1 = new Base;
    	Derived *pd1 = dynamic_cast<Derived *>(pb1); //失败,pd1 = NULL
    
    	//子类 -> 子类
    	Base *pb2 = new Derived;
    	Derived *pd2 = dynamic_cast<Derived *>(pb2); //成功
    
    	//子类 -> 基类
    	Base *pb3 = new Derived;
    	Base *pd3 = dynamic_cast<Base *>(pb3);		 //成功
    }

    dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
    在类层次间进行上行转换(子类->子类/基类)时,dynamic_cast和static_cast的效果是一样的;在进行下行转换(基类->子类)时,dynamic_cast具有类型检查的功能,比static_cast更安全。

    4. reinterpret_cast重述转换

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

    reinterpret_cast<T>(expression);

    T必须是一个指针、引用、算术类型、函数指针或者成员指针。

    该操作符用于将一种类型转换为另一种不同的类型,比如可以把一个整型转换为一个指针,或把一个指针转换为一个整型,因此使用该操作符的危险性较高,一般不应使用该操作符。

    示例:

    int i;
    char *p = "This is a example.";
    i = reinterpret_cast<int>(p);   //将指针p的值(即地址)转为int型 【如 0x00b4cd10 -> 11848976】

    5. const_cast转换

    const_cast<T>(expression);

    其中T必须为指针或引用 。

    主要是用来去掉const属性,当然也可以加上const属性。主要是用前者,后者很少用。

    class A
    {
    public:
    	int num;
    };
    
    void main()
    {
    	//类指针
    	const A a;
    	const A* pA = &a;
    	pA->num = 10;                //compile error
    	A* pA2 = const_cast<A*>(pA);
    	pA2->num = 11;               //success
    
    	//基本数据类型
    	const int i = 3;
    	int* p = const_cast<int*>(&i);
    	*p = 10;                     //success
    
    	//加上const属性
    	int j = 10;
    	const int* k = const_cast<const int*>(&j);//一般可以直接写const int* k = &j;
    }








  • 相关阅读:
    mouse_event模拟鼠标滚轮
    润乾报表配置技术路线
    建筑 物件 开心背单词 读句子,单词,字母,看图例, 翻译,看动画
    文字过渡动画,曲线过渡动画,,使用这个插件assign shape keys
    运动锻炼 开心背单词 读句子,单词,字母,看图例, 翻译,看动画,学英语,轻松背单词,简单背单词
    blender293 内置插件 精度绘画控件,PDT学习003,pdt tangents 切线
    日常用品 背单词 读句子 看图片 读单词 读字母 翻译, 看动画 学英语
    blender293 内置插件 精度绘画控件,PDT学习 precision drawing tools
    乔布斯 背单词 02 读句子 单词 字母 翻译,看动画 学英语 名言 我菜顾我在,我菜故我在,blender加python
    狐狸 和 乌鸦 英语 朗读句子 背单词
  • 原文地址:https://www.cnblogs.com/fzll/p/3954579.html
Copyright © 2011-2022 走看看