一些内容在C语言中展开讲了,不再赘述。
在表达式求值过程中,只要能都转换为同一种类型就满足要求。
小整数类型(bool、char、short等)通常被提升为较大的整数类型(主要是int)
重载运算符
最常见的是io操作的<<和>>运算符,有多重含义。
在c++中,当一个对象用作右值时,用的是对象的值;当一个对象作为左值时,用的是对象的身份(内存地址)若一个左值被当成右值来使用,使用的是对象的内容
如果表达式的求值结果是左值,decltype作用于表达式得到一个引用类型
算术运算符的运算对象和求值结果都是右值。
1.整数相除的结果还是整数
2.取余运算的运算对象必须是整数类型
3.在除法运算中,如果两个运算对象符号相同,则商为正
4.除了-m导致溢出的情况,(-m)/n和m/(-n)都等于-(m/n),m%(-n) =m%n,(-m)%n = -(m%n)
逻辑与和逻辑或有短路求值
引用类型是绑定不是拷贝
关系运算符的求值结果是bool类型,【不能连着写】if(1<i<10)
进行比较运算时除非比较的对象是bool类型,否则不要用true和false
如果赋值运算符的左右两个运算对象的类型不同,则右侧对象转化成左侧运算对象的类型。
使用复合赋值运算符时和正常的赋值区别:左侧运算对象的求值次数不同
1.使用复合运算符只求值一次
2.普通的运算符求值两次:一次是作为右边子表达式的一部分求值,另一次是作为赋值运算的左侧运算对象求值。
自增自减运算符 【前置】和【后置】
1.对于自增操作,前++更快,避免了不必要的工作
2.前置版本将对象本身作为左值返回
3.后置版本将对象原始值的副本作为右值返回,需要将这个原始值存储来返回这个未修改的内容。
位运算符仅建议用于处理无符号类型
sizeof运算符
sizeof运算符返回一条表达式或一个类型名字所占的字节数。
满足右结合律,返回一个size_t类型,但并不计算运算对象的值
对于不同类型的结果:
1.对char或者类型为char的表达式,结果是1
2.对引用类型,得到被引用对象所占空间的大小
3.对指针,得到指针本身所占空间的大小
4.对解引用指针,得到指针指向对象所占空间的大小,指针不需有效
5.对数组,得到整个数组所占空间的大小
6.对string对象或者vector对象,返回该类型固定部分的大小
怎么得到数组中元素的个数
sizeof(a1) / sizeof(*a1)
类型转换
算术类型之间的隐式转换应尽可能避免损失精度 -----{如果表达式中既有整数类型的运算对象又有浮点数类型的运算对象,整型会转换为浮点型}
那么何时发生隐式转换呢?
1.比int类型小的整型值首先提升为较大的整数类型
2.在条件中,非布尔类型转换为布尔类型
3.初始化过程中,初始值转换为变量的类型;赋值操作中,右值运算对象的类型转换为左侧运算对象的类型
在算术运算中
运算符的运算对象将转换成最宽的类型
这里来说明一下**整型提升:**将小整数类型转换成较大整数类型(前提是转换后的类型要能容纳原类型所有可能的值)
在无符号中,看运算对象。
1.如果一个运算对象是无符号类型,另一个运算对象是带符号类型,而且其中的无符号类型不小于带符号类型,那么带符号的运算对象转换成无符号的。
2.如果带符号类型大于无符号类型,转换结果依赖于机器。如果无符号类型的所有值都存在该带符号类型中,则无符号类型转换为带符号类型。
其他的像数组名字转换为指针
指针的转化:1.常量整数值0和字面量nullptr转换为任意指针类型。2.指向任意非常量的指针能转换成void*。3.指向任意对象的指针能转换为const void*
像内置类型一样,也可以转换为常量。允许将指向非常量类型的指针转换成指向相应的常量类型的指针。引用也是如此。
还有类类型定义的转换
类类型定义由编译器自动执行的转化,但编译器每次只能执行一种类类型的转换
string s, t = "a value";
while(cin >> s)
强制类型转换
命名的强制类型转换cast-name<type>(expression)
,其中cast-name是static_cast,dynamic_cast,const_cast和reinterpret_cast
static_cast:任何具有明确定义的类型转换,只要不包括底层const,都可使用static_cast
static_cast可以用来找回存在于void*指针中的值
void* p = &d; //任何非常量对象的地址都能存入void*
double *dp = static_cast<double*>(p); //将void*转换为初始的指针类型
**注:**把指针存放在void*中,而且使用static_cast强制转回原来的类型,应确保指针的值保持不变。强制转换的结果将与原始的地址一样。必须确保转换后的所得的类型就是指针所指向的类型。 类型不符产生未定义行为。
const_cast只能更改运算对象的底层const,只有const_cast能改变表达式的常量属性。 也不能改变表达式的类型。
将常量对象转换成非常量的对象,称为去掉const性质
1.如果对象本身不是一个常量,使用强制类型转换获得写权限是合法的。
2.如果对象是一个常量,再使用const_cast执行写操作会产生未定义行为。
const char *pc;
char *p = const_cast<char*>(pc); //正确,但通过P写值是未定义的
const char *cp;
static_cast<string>(cp); //字符串字面量转换成string类型
const_cast<string>(cp); //const_cast只改变常量属性,错误
reinterpret_cast
通常为运算对象的位模式提供较低层次上的重新解释
int *ip;
char *pc = reinterpret_cast<char*>(ip);
必须记住pc所指的对象是一个int而不是字符,如果把pc当做普通的字符指针使用会在运行时发生错误。
与C语言旧式强制类型转换有些许不同。