c++中包含两种形式的类型转换,一种是隐式类型转换,也是自动类型转换,这件事是由编译器悄悄来做。一种是强制类型转换,需要用户自己进行强制转换,下面分别总结下这两种类型转化。
(一)隐式类型转换
1:算术运算(+,-,*,/)
这类转换中有一个很好记的规则:小转大,目的是不丢失数据精度,c++在进行运算之前,会将运算值转化成同一类型。编译器在运算过程中自动转换。
A:int a=1 ;long b=2.2; a+b;// 将int 型a转化成long型b
B: char a='a', int b=2 ; a+b; // char型转化成int型
还有一个类型转换目前不知道规划到哪一种范围:
char a='a'; int num[256]={}, num[a] =10; 这里a被自动转换成了整形:acII码
需要注意的是:
(1)有符号和无符号数的转换:有符号数会被自动转换成了无符号数。
(2) bool类型和整形之间的相互转化
2:赋值操作
进行赋值运算时,预算符右边的类型会被自动转化为左边的类型,如果右边精度较高,编译器会自动进行截断操作。
long c=‘.....’; int a =c;
3: 函数调用、返回
函数调用中,参数类型不匹配,如果隐式转换后能满足类型匹配条件,编译器将启用类型转换。
这类转换也常发生在类对象的类型转换。
#include <string>
#include <iostream>
using namespace std;
class Fruit //定义一个类,名字叫Fruit
{
string name; //定义一个name成员
string colour; //定义一个colour成员
public:
bool isSame(const Fruit &otherFruit) {
return name == otherFruit.name;
}
void print() //定义一个输出名字的成员print()
{
cout<<colour<<" "<<name<<endl;
}
Fruit(const string &nst,const string &cst = "green"):name(nst),colour(cst){} //构造函数
Fruit(){}
};
int main()
{
Fruit apple("apple");
Fruit orange("orange");
cout<<"apple = orange ?: "<<apple.isSame(orange)<<endl; //没有问题,肯定不同
cout<<"apple = /"apple/" ?:"<<apple.isSame(string("apple")); //(2)
return 0;
}
(2)中用一个string类型作一个期待Fruit类形参的函数的参数,结果竟然得出了是true(1),神奇!,这里就是一个典型的隐式类类型转换:“可以用单个实参来调用的构造函数定义了从形参类型到该类型的一个隐式转换”,必须要满足这个条件,编译器才知道怎么进行类型转换,否则编译不能通过
这样做的缺点是会导致不合理的类型转换,合理的解决方案:为单参数的构造函数加上explicit
(二)强制类型转换
c++的任何类型几乎都可以用线面的表达式进行强制类型转化 type1 a = type1(type2);
除此之外,c++提供了四种强制转换操作符:
(1)const_cast 消除常量性
(2)dynamic_cast: 主要用于执行“安全的向下转型(safe downcasting)”,将基类类型的指针或引用安全地转换为派生类型的指针或引用。而默认派生类类型指针可以自动的转化为基类类型指针。
(3)static_cast :todo