1.自动类型转换
在c++中,整型、实型、字符型、布尔类型都可以参加算术运算。但事实上,c++只能执行同类型的数据的运算。例如,int与int型数据进行运算,double与double型的数据进行运算。在进行不同类型的数据运算之前,系统会自动将运算数转换成同一类型,再进行运算。这种运算称为自动类型转换。转换的总原则:非标准类型转换成标准类型,占用空间少的向占用空间多的靠拢,数值范围小的向数值范围大的靠拢。具体规则如下:
- bool、char和short这些非标准的整数在运算前都必须转换成int。
- int和float运算时,将int转换成float。
- int和long运算时,将int转换成long。
- int和double运算时,将int转换成double。
- float和double运算时,将float转换成double。
其中实型转换成整型时,舍弃小数部分。整型转换成实型时,数值不变,但表达式成实型形式。字符型转换成整型时,不同的编译器有不同的处理方法。布尔类型转换成整型时,true为1,false为0。整型转换成字符型时,直接取整数数据的最低8位。
2.强制类型转换
2.1 c语言中的强制类型转换
c语言中的类型转换只有一种。
比如下面的例子
TYPE b = (TYPE)a;
需要注意的是:如果强制类型转换的对象是一个变量,那么该变量不需要用括号括起来;但是如果对象是一个包含多项的表达式,则表达式应该用括号括起来。
2.2 c++的强制类型转换有四种:
方式一:
(typName) value //这个格式来自c语言
typeName (value) //这种格式是纯粹的c++语言,为了让强制类型转换就像函数调用一样
类型名 (表达式)
//例如下面类型转换结果是一样的
char a='A';
(int) a//正确
int (a) //正确
上边的强制类型转换不会修改char型变量a的值,而是创建一个新的、指定类型的值。
但一般情况下尽可能避免使用强制类型转换,它只是用于解决非常特殊的问题的手段。
方式二:c++引入的强制类型转换符
- dynamic_cast(动态转换)
dynamic_cast<typeName> (expression)
用途:是的能够在类层次结构中进行向上转换,而不允许其他转换。
例如:假设High和Lows是两个类,ph是High*指针,pl是Low*指针,则仅当Low是High可访问基类(直接或间接)时,下面的语句才能将一个Low*指针赋给pl;
pl=dynamic_cast<Low*> ph;//将High*指针类型转换成Low*类型
- const_cast(常量转换)
该运算符用于执行只有一种用途的类型转换,即把值改变为const或volatile。如果类型的其他方面也被修改,则上述类型转换则将出问题。
const_cast <typeName> (expression)
有时候可能需要这样一个值,它在大多时候是常量,而有时有时又是可以修改的,在这种情况下可以将这个值声明为const,并在需要修改它的时候使用const_cast。
#include <iostream>
#include <fstream>
using namespace std;
void change(const int * pt, int n);
int main()
{
int pop1 = 38383;
const int pop2 = 2000;
change(&pop1, -103);
change(&pop2, -103);
int a = pop2;
cout << a << endl;
cout << "pop1,pop2:" << pop1 << "," << pop2 << endl;//pop1的值可以改变,pop2的值不能改变
return 1;
}
void change(const int * pt, int n)
{
int *pc;
pc = const_cast<int*>(pt);
*pc += n;
}
注意:const_cast不是万能的,它可以修改指向一个值的指针,但修改const值的结果是不确定的。
- reinterpret_cast(重解释转换)
reinterpret_cast <type-name> (expression)
reinterpret_cast是C++中与C风格类型转换最接近的类型转换运算符。它让程序员能够将一种对象类型转换为另一种,不管它们是否相关
reinterpret_cast用在任意指针(或引用)类型之间的转换;以及指针与足够大的整数类型之间的转换;从整数类型(包括枚举类型)到指针类型,无视大小。
- static_cast(静态转换)
static_cast<type-name> (expression)
仅当type-name可被隐式转换为expression所属的类型或expression可被隐式转换为type-name所属类型时,上述转换才合法,否则出错
转换类型 <类型名>(表达式)
char ch;
int a;
double c=10.56;
int d=10;
ch=static_cast<char>(d);//将int类型的d转换成 char类型的 ch
a=static_cast<int>(c);//将double类型的c转换成 int类型的 a
当需要把一个占用空间较大的类型赋给一个占用空间较小的类型时,使用静态类型转换非常有用。此时静态转换告诉程序的读者和编译器:我们知道并且不关心潜在的损失。如果不加静态转换,编译器通常会产生一个警告,加了静态转换后,编译器就会关闭警告信息。