第三章之类型转换

初始化和赋值进行的转换

这里提到的三种潜在的数制转换问题分别是
1.较大的浮点类型转为较小的浮点类型,会导致精度下降,比如double–>double,值可能超出目标类型的取值范围,在这种情况下,结果将是不确定的

#include<iostream>
//#include<limits>
//#include<cfloat>
using namespace std;

int main()
{
	double a = 10.0 / 3.0;
	float b = 10.0 / 3.0;
	const float million = 1.0e6;
	cout.setf(ios_base::fixed, ios_base::floatfield);
	cout << a* million << endl;
	cout << b* million << endl;
	cout << a * million* million << endl;
	return 0;
}

3333333.333333
3333333.250000
3333333333333.333496
可以在cfloat这个头文件中看到,float的最小有效位数为6位,
double15位,通过上面的例子可以看到,
float在第七位小数之后出现了错误,但是double直到第十五位之后才出现错误

2.将浮点转换为整型,这种情况很常见,小数部分会丢弃
3.将较大的整形转换为较小的整形,比如long->short

以 {}方式进行转换

这种方式不允许把精度高的转换位精度低的
在这里插入图片描述

表达式中的转换

这里书上总结了很多,一共分为两类

  1. 自动转化,在bool char unsigned char,signed char, short出现时,自动转换为int,这被称为整型提升
  2. 在不同类型的的变量进行运算时,也会进行转化吗,总结成一句话就是,把精度低的变量转换成精度高的变量进行计算

强制转换

之前我们常见的作法就是
(typeName) value 或者 typeName(value)
后来C++11 引入了四种强制类型转换运算符,可以根据目的选择一个适合的运算符,而不是使用通用的类型转换。这只出了进行类型转换的原因,并让编译器能够检查程序的行为是否与设计者想法相吻合

dynamic_cast

#include<iostream>
using namespace std;

class Low
{
public:
	int a;
};

class High : public Low
{
public:
	int b;
};


int main()
{
	High* ph = new High;
	Low* pl = dynamic_cast<Low *>(ph); //允许
	Low* p2 = ph; //允许

	Low* p3 = new High;
	High *ph1 = p3; //编译不允许,因为子类指针不能直接指向父类空间
	High* ph2 = (High *)p3; //强制转换之后,编译允许
	High* ph3 = dynamic_cast<High*>(p3);//采用C++11 编译不允许
	return 0;
}

上面这种转换,仅当Low是High的可访问基类时,才能进行,那么什么是可访问基类呢?
参考下面这个博客 https://www.cnblogs.com/zhaoyl/p/4966865.html

const_cast

这种转换,只能改变值为const 或者 volatile,关于const和* 可以参考我之前的博客
https://blog.csdn.net/qq_36437446/article/details/103099507在这里的第四部分
如果有一个值,大多数时是常量,有时又是可以修改的,在这种情况下,可以将值声明为const,当需要修改的时候,使用这种转换。

#include<iostream>
using namespace std;

class Low
{
public:
	int a;
};

class High : public Low
{
public:
	int b;
};


int main()
{
	High bar;
	bar.a = 10;
	const High* pbar = &bar;
	//pbar->a = 11; //这里编译时通不过的,因为pbar指向一个const 的High型数据
	High* pb = const_cast<High*>(pbar);
	pb->a = 100;
	//const Low* p1 = const_cast<const Low*>(pbar); //不允许,因为尝试修改变量类型从High *到Low *
	return 0;
}

还有一点需要注意

#include<iostream>
using namespace std;

void change(const int*, int);
int main()
{

	int pop1 = 100;
	const int pop2 = 200;
	cout << "pop1:" << pop1 << "  pop2:" << pop2 << endl;
	change(&pop1, -20);
	change(&pop2, -20);
	cout << "pop1:" << pop1 << "  pop2:" << pop2 << endl;
	return 0;
}

void change(const int* pt, int n)
{
	int* pc;
	pc = const_cast<int*>(pt);
	*pc += n;
}

pop1:100  pop2:200
pop1:80  pop2:200

这里为什么pop2的值没有被修改呢,因为虽然无法通过pt进行修改,因为pt 的类型是指向const int型数据的指针,但是通过const_cast取消了pt的const属性,所以pop1得以修改,但是因为pop2这个值本身就是const,他是不可被修改的

这里我理解的也不是太好,只是先记住了,以后相同了,再回来解释

static_cast

还是上面的High 和 Low类
High bar;
Low blow;
High *pb = static_cast<High *>(&blow) //OK
Low * pl = static_cast<Low *>(&bar) //ok
如果这里有一个独立的类A
A * a = static_cast<A *>(&bar) //不允许

reinterpret_cast

这种转换适用于依赖于实现的底层编程技术,目前我还没有遇到股,这里不进行介绍

欢迎大家批评指正

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章