c++ primer 阅读手记 第四章
1、左值和右值
使用关键字decltype的时候,左值和右值也有所不同。
如果表达式的求值结果是左值,decltype作用于该表达式(不是变量)得到一个引用类型。
假设p的类型是int*,因为解引用运算符生成左值,所以decltype(*p)的结果是int&。
因为取地址运算符生成右值,所以decltype(&p)的结果是int **,指向整型指针的指针。
2、赋值运算符
int k = 0;
k = 3.1415; //k的值是3
k = {3.14}; //错误
//C++11新标准允许使用花括号括起来的初始值列表作为赋值语句的右侧运算对象,
//如果左侧运算对象是内置类型,那么初始值列表最多只能包含一个值,
//而且该值即使转换的话其所占空间也不应该大于目标类型的空间。
3、关系运算符
if(i < j < k) //比较顺序:拿i < j的结果再与k比较,而i < j的结果为布尔值:0或1
4、递增递减运算符
建议:除非必要,否则不用递增递减运算符的后置版本
int i = 0, j;
j = ++i; //j = 1, i = 1:前置版本++i返回运算后的值
j = i++; //j = 1, i = 2:后置版本i++返回运算前的值,而非先赋值给j,再执行++运算
auto pbeg = v.begin();
while (pbeg != v.end() && *beg >= 0)
cout << *pbeg++ << endl;
//*pbeg++ 等价于 *(pbeg++)
//先进行后置递增,再返回运算前的值
//最后解引用运算符的运算对象是pbeg未增加之前的值。
//等价于:
//cout << *pbeg << endl; ++pbeg;更常见的是上面的写法
5、成员访问运算符
ptr->mem 等价于 (*ptr).mem,所以指针访问成员使用箭头运算符(->)。
6、位运算符(二进制)
~:位求反;^:位异或,同为0或1,结果为0,不同时为1。
7、移位运算符(又叫IO运算符)
位运算符的重载版本:cout << “hi” << endl;
8、显式转换
命名的强制类型转换:
int i, j;
double slope = i / j;
//cast-name<type>(expression);
//cast-name:static_cast、dynamic_cast、const_cast 和 reinterpret_cast中的一种
//static_cast:任何具有明确定义的类型转换,只要不包含底层const
double slope = static_cast<double>(j) / i;
//const_cast:只能改变运算对象的底层const
const int ap = 10;
const int *pc = ≈
int *p = const_cast<int*>(pc); //正确,去掉const性质
*p = 20;
cout << *p << endl; //输出结果:20
string s1 = "asd";
string &s2 = s1;
const string &s3 = const_cast<const string&>(s2);//添上const属性
const_cast<string>(pc); //错误:const_cast只能改变常量属性
//reinterpret_cast:通常为运算对象的位模式提供较低层次上的重新解释
旧式的强制类型转换
type (expr);
(type) expr; //char *pc = (char*) ip; //ip是指向整数的指针