第四章
左值右值
-
当对象被用作左值的时候,用的是对象的身份(在内存中的位置);当一个对象被用作右值的时候,用的是对象的值(内容)。
-
使用关键字decltype时,如果表达式的求值结果是一个左值,decltype作用于该表达式(不是变量)得到一个引用类型。
int i = 4;
const int j = 5;
int arr[5] = { 0 };
int *ptr = arr;
//表达式的结果为左值,推导为类型的引用
decltype((i)) var1 = i; //int& 有括号是一个表达式
decltype(true ? i : i) var2 = i; //int& 条件表达式返回左值。
decltype(++i) var3 = i; //int& ++i 前置返回i的左值。
decltype(arr[5]) var4 = i; //int& []操作返回左值
decltype(*ptr) var5 = i; //int& *操作返回左值
decltype("hi") var6 = "hi"; //const char(&)[3] 字符串字面常量为左值,且为const左值。
//右值,则推导为本类型
decltype(1) var7 = 10; //int
decltype(i++) var8 = i; //int i++ 后置返回右值
decltype(&ptr) var9 = &arr; //int **
处理符合表达式
- 拿不准的时候就加括号。
- 如果改变了某个运算对象的值,在表达式的其他地方不要再使用这个运算对象。
取模%
表达式(m/n)*n+m%n的求值结果与m相等,即如果m%n!= 0,则符号与m相同。
递增递减运算符
一般选择使用前置,因为后置版本需要将原始值存储下来以便于返回这个未修改的内容。
解引用
解引用运算符的优先级低于点运算符。
sizeof
sizeof运算符不会把数组转换成指针来处理,会得到整个数组的大小。
命名的强制类型转换
static_cast
任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。
double d = 10;
void *p = &d;
double* a = static_cast<double*>(p);
使用static_cast强转时,应确保指针的值不变,是原本的类型。
const_cast
const_cast只能用来改变底层const,常用于函数重载的上下文中。
const char *pc;
char *p = const_cast<char*>(pc); //正确,但是不能通过p写值
注:避免强制类型转换