我是靠谱客的博主 清爽大树,最近开发中收集的这篇文章主要介绍【C++】【类型转换】C++类型转换的五种方式,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

C风格强制转换
即通过圆括号直接转型,常见有以下几种情况:

  • 浮点数赋值给整型,舍弃小数部分(符合一般思维,可放心使用)
  • 整数赋值给浮点型,数值不变,底层改用指数格式存储(符合一般思维,可放心使用)
  • double型小数赋值给float型小数,精度略微损失,可能出现数值范围溢出(小心使用)
  • 字符赋值给整数型,保留原字节数据,因为字符本身就是用ASCII码表示的,本质就是八位的较小整数(理解字符的存储方式,就很容易接受)
  • 整数赋值给字符型,截断高地址数据,只保留低地址的八位,因为char型最多只有八位(小心使用)
  • 有符号整数赋值给无符号整数,将包括符号在内的全部字节的直接赋值,实际数值会改变(小心使用)
  • 无符号整数赋值给有符号整数,也是将包括符号在内的全部字节的直接赋值,但是数值可能会改变(小心使用)
  • unsigned int和int字节存储区别:unsigned int和int位数是一样的,但是int将首个bit位作为正负号,0表示正数,1表示负数。unsigned int和int之间都是以字节的方式相互赋值。当字节以0开头时,它们表示的数值是相同的,当字节以1开头时,它们则分别表示整数和负数。由于int将首位作为符号位,因此它实际能表示的最大正整数只有unsigned int的一半

static_cast静态转换
类似C风格的强制转换,只允许在有关联的指针类型或基本类型间使用
比如基类指针和子类指针,int和double,对象指针和void指针


	int main() {
	    double a = 1099.255;
	    int b = static_cast<int>(a);
	    char c[] = "hello";
	    string d = static_cast<string>(c);
	    cout << a << endl;
	    cout << b << endl;
	    cout << c << endl;
	    cout << d << endl;
	    return 0;
	}

dynamic_cast动态转换
用于基类指针和子类指针之间的转换
虽然static_cast也具备这样的功能,但是是不安全的,dynamic_cast则会在转型时判断类型,如果类型不符则返回nullptr
由于类型信息是保存在虚函数表中的,因此dynamic_cast操作的基类必须包含virtual函数
不要觉得这个限制很麻烦,因为dynamic_cast的定位就是在多态场景下使用的


	class Animal {
	    virtual void speak() {}
	};
	
	class Cat : public Animal {
	    void speak() {}
	};
	
	class Dog : public Animal {
	    void speak() {}
	};
	
	int main() {
	    Cat *a = new Cat;
	    Animal *b = dynamic_cast<Animal *>(a);
	    Cat *c = dynamic_cast<Cat *>(b);
	    Dog *d = dynamic_cast<Dog *>(b);
	
	    cout << a << endl;
	    cout << b << endl;
	    cout << c << endl;
	    cout << d << endl;
	    return 0;
	}

reinterpret_cast重译转换
reinterpret_cast用于将地址,强制转换为任意类型的指针
顾名思义,reinterpret_cast就是不改变指针地址,但是强制将地址处的内存字节解释为某种类型的数据


	class Object {
	  public:
	    char h = 'H';
	    char i = 'I';
	    char j = 'J';
	    int m = 100;
	    int n = 200;
	    int k = 300;
	    int x = 400;
	    int y = 500;
	    int z = 600;
	};
	
	int main() {
	    Object a;
	    double *b = reinterpret_cast<double *>(&a);
	    bool *c = reinterpret_cast<bool *>(&a);
	    char *d = reinterpret_cast<char *>(&a);
	    int *e = reinterpret_cast<int *>(&a);
	    int *f = reinterpret_cast<int *>(&a.m);
	
	    cout << &a << endl;
	    cout << *b << endl;
	    cout << *c << endl;
	    cout << *d << endl;
	    cout << d[1] << endl;
	    cout << d[2] << endl;
	    cout << *e << endl;
	    cout << *f << endl;
	    return 0;
	}

const_cast常量转换
const_cast用于常量指针和非常量指针间的转换,同样适用于引用
函数和模块接口,由于会暴漏给很多文件或代码使用,难免会遇到需要修改const属性的情况,因为凡事总有特例,不可能一个接口适用于所有情景
即便是在单个文件中,我们也可能希望某个变量在大多时候值不被修改,但是在某个特定地方却又必须修改它的值,这时const_cast就派上用场了
const_cast提供了一个解决特殊需求的捷径,但是不应当滥用,否则const属性就失去意义了


	int *getValue() {
	    return new int(10);
	}
	
	int main() {
	    //const转非const
	    int a = 100;
	    //定义一个指针pa,我们希望通过它来访问a,但是不希望它修改a的值,所以定义为const int *
	    const int *pa = &a;
	    //之后我们遇到一个特殊情况,必须得修改a的值,所以我们临时去除pa的const属性,赋值给pb
	    int *pb = const_cast<int *>(pa);
	    //通过pb修改a的值,完成其特殊使命后,我们应当继续使用pa
	    //注意,这里的a并不是const的,否则我们将无法修改a的数值
	    //我们只是将pa定义为const,禁止pa修改a的值而已
	    *pb = 200;
	    pb = nullptr;
	    //测试a的值
	    cout << a << endl;
	
	    //非const转const
	    //我们不希望函数的返回值被修改,所以将其转为const的
	    const int *pe = const_cast<const int *>(getValue());
	
	    return 0;
	}

最后

以上就是清爽大树为你收集整理的【C++】【类型转换】C++类型转换的五种方式的全部内容,希望文章能够帮你解决【C++】【类型转换】C++类型转换的五种方式所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(48)

评论列表共有 0 条评论

立即
投稿
返回
顶部