本文共 2052 字,大约阅读时间需要 6 分钟。
在C++语言中,左值表达式的求值结果是一个对象或函数,而某些表达式的结果虽然是对象,但它们是右值而非左值。左值和右值的主要区别在于,当对象作为左值使用时,会使用对象的身份(内存地址),而作为右值时,会使用对象的内容(值)。
string
和vector
的下标运算符:这些运算符的结果都是左值。decltype
的使用decltype
用于获取表达式的类型。若表达式结果为左值,则结果为引用类型。例如,p
为int*
,*p
为左值,decltype(*p)
为int&
。而&p
为右值,decltype(&p)
则为int**
。
赋值运算符的左侧运算对象必须是可修改的左值。以下操作均为非法:
1024 = k
:右值。i + j = k
:右值。ci = k
:ci
为常量,无法修改。C++11允许初始值列表作为右侧运算对象,但内置类型最多只能有一个初始值,且初始值可能导致类型转换。例如:
int a = {3.14}; // 错误:窄化转换int vi; // 初始化为空int a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // 正确
在一条语句中混用解引用和递增运算符时,后置递增运算符优先级高于解引用。例如:
auto pbeg = v.begin();while (pbeg != v.end() && *pbeg >= 0) { cout << *pbeg++; // 等价于 (*(pbeg++))}
点运算符和箭头运算符用于成员访问。ptr->mem
等价于(*ptr).mem
。
位与、位或、位异或运算符在两个运算对象上逐位执行相应逻辑:
&
:结果位为1当且仅当两位均为1。|
:结果位为1若至少一位为1。^
:结果位为1当且仅当两位中一位为1。类型转换分为隐式和显式两种。隐式转换通常发生在算术运算和初始化时,例如int ival = 3.14 + 3
中3.14
和3
转换为double
和int
。显式转换使用static_cast
、const_cast
、reinterpret_cast
等关键字。
decltype
、&
、sizeof
、typeid
等情况下不会转换。0
或nullptr
可以转换为任意指针类型。非常量不能转换为常量(const
),但常量可以转换为非常量。例如:
int i;const int& j = i; // 错误:非常量转换成const int的引用const int* p = &i; // 非常量地址转换成const地址int& r = j, *q = p; // 错误:const不能转换成非常量
类类型可以通过定义显式转换运算符实现自定义转换。例如,Sales_item
类可能定义了operator+
使得两个Sales_item
对象相加。
显式转换使用cast-name
形式,如static_cast
、const_cast
、reinterpret_cast
。static_cast
用于明确类型转换,如double slope = static_cast<double>(j) / i
。const_cast
用于去掉const
属性,如char* p = const_cast<char*>(p)
。reinterpret_cast
用于重新解释位模式,如char* pc = reinterpret_cast<char*>(ip)
。
try
语句块和异常声明try
语句块用于异常处理,throw
表达式用于抛出异常。例子:
if (item1.isbn() != item2.isbn()) throw runtime_error("Data must refer to same ISBN");cout << item1 + item2 << endl;
try
语句块后面跟着catch
子句,处理抛出的异常。try
块内的变量无法在catch
子句中访问。
异常从当前函数传播到调用者,直到找到匹配的catch
子句。如果无匹配,调用terminate
函数终止程序。
stdexcept
头文件定义了多种异常类,如runtime_error
、out_of_range
等。异常对象通过what()
方法返回描述信息。
本章涵盖了C++语言中的左值和右值、赋值运算符、类型转换以及异常处理。理解这些概念对于编写高效且健壮的C++程序至关重要。
转载地址:http://eyhwz.baihongyu.com/