表达式基础
重载运算符:当运算符作用于类类型的运算对象时,用户可以自行定义其含义。左值和右值:
C中原意:左值可以在表达式左边,右值不能。C++:当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。
解引用运算符生成左值,decltype(*p)的结果为int &取地址符生成右值,decltype(&p)的结果为int **,是一个指向整型指针的指针
逻辑运算符
短路求值:逻辑与运算符和逻辑或运算符都是先求左侧运算对象的值再求右侧运算对象的值,当且仅当左侧运算对象无法确定表达式的结果时才会计算右侧运算对象的值。
赋值运算符
如果赋值运算的左右侧运算对象类型不同,则右侧运算对象将转换成左侧运算对象的类型。赋值运算符满足右结合律,这点和其他二元运算符不一样。 ival = jval = 0;等价于ival = (jval = 0);赋值运算优先级比较低。
说明前置递增运算符和后置递增运算符的区别。
b前置递增运算符将对象本身作为左值返回,而后置递增运算符将对象原始值的副本作为右值返回。
假设iter的类型是vector::iterator, 说明下面的表达式是否合法。如果合法,表达式的含义是什么?如果不合法,错在何处?
(a) *iter++;
(b) (*iter)++;
(c) *iter.empty();
(d) iter->empty();
(e) ++*iter;
(f) iter++->empty();
(a
)合法。返回迭代器所指向的元素,然后迭代器递增。
(b
)不合法。因为vector元素类型是string,没有
++操作。
(c
)不合法。这里应该加括号。
(d
)合法。判断迭代器当前的元素是否为空。
(e
)不合法。string类型没有
++操作。
(f
)合法。判断迭代器当前元素是否为空,然后迭代器递增。
移位运算符满足左结合律
sizeof运算符
返回一条表达式或一个类型名字所占的字节数,满足右结合律。返回的类型是 size_t。两种形式: sizeof (type)和 sizeof expr
逗号运算符
含有两个运算对象,按照从左向右的顺序依次求值
隐式类型转换
在大多数表达式中,比 int类型小的整数值先提升为较大的整数类型。在条件中,非布尔值转换成布尔类型。在初始化中,初始值转换成变量的类型。在赋值语句中,右侧运算对象转换成左侧运算对象的类型。算术运算或者关系运算的运算对象有多种类型,需要转换成同一种类型。函数调用时。
显式类型转换
static_cast:任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。
double slope
= static_cast
<double>(j
);
dynamic_cast:支持运行时类型识别。
const_cast:只能改变运算对象的底层const,一般可用于去除const性质。
const char *pc
;
char *p
= const_cast
<char*>(pc
);
reinterpret_cast:通常为运算对象的位模式提供低层次上的重新解释。
int *ip
;
char *pc
=reinterpret_cast
<char*>(ip
);
说明下面这条表达式的含义。
double slope = static_cast<double>(j/i);
将j/i的结果值转换为double,然后赋值给slope
try语句块和异常处理
throw表达式:异常检测部分使用 throw表达式来表示它遇到了无法处理的问题。我们说 throw引发了异常。try语句块:以 try关键词开始,并以一个或多个 catch字句结束。 try语句块中的代码抛出的异常通常会被某个 catch捕获并处理。 catch子句也被称为异常处理代码。
throw
runtime_error("");
异常类:用于在 throw表达式和相关的 catch子句之间传递异常的具体信息。
runtime_error error
;
error
.what();