提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
介绍
C++Primer第四章学习心得
一、基础
1.1 运算符重载
当运算符作用于类类型的运算对象时,用户可以自行定义其含义,即运算对象的类型和返回值的类型可以根据作用对象进行修改,运算对象的个数、运算符的优先级和结合律时无法改变的
1.2 左值和右值
左值:用的是对象的身份(在内存中的地址)
右值:用的是对象的值(内容)
因此,有些时候可以用左值代替右值,实际用的是左值地址中的内容;但不可用右值代替左值。
使用decltype时,左值和右值不一样,作用于左值时得到的时一个引用类型。例如:int*p;decltype(p);
获得的结果时int &
;针对decltype(&p);
时,获得的结果时int **
1.3 求值顺序
求值顺序与运算符优先级、结合性无关,当运算对象互不关联时,求值顺序不影响结果,当相互关联是,则该表达式错误,会产生未定义的行为。
f() + g() * h() + j()
上述表达式中,求值顺序不确定,因此该函数涉及同一对象时,可能报错。
有4种运算符明确规定了运算顺序:"&&" "||" " ?:" " ,"
二、算术运算符
取余和除法:
关于取余后的符号问题,把握原则:以被取余数为准。
21%8 = 5
21%-8 = 5
-21%8 = -3
-21%-8 = -3
即m%n、m%(-n)相同,-m%-n、-m%n相同等于 -(m%n)
关于除法后的取整问题,把握原则:向0取整
21/-5 = -4
-21/5 = -4
三、递增和递减运算符
运算符在前,返回+1后对象本身
运算符在后,返回对象原始值副本,浪费空间
四、位运算
针对整型
由于符号位如何处理未明确规定,因此位运算通常只针对无符号数
五、sizeof运算
核心思想:返回类型大小,而不是对象大小
主要有两种用法:括号对象 直接表达式
sizeof(type)
sizeof expr
特别的:
对解引用指针使用sizeof得到的指针指向的对象所占空间的大小,指针不需有效
int *p;
sizeof *p;
返回int的大小,而非指针本身
针对数组名时,不会将其看作指针,而是获得整个数组空间的空间大小
int a[10];
constexpr size_t t = sizeof(a)/sizeof(*a);
int arr[t];
可以通过上述方式,获得a数组的空间大小和元素个数
六、类型转换
命名的强制类型转换:cast_name (expression)
cast_name 有四种:static_cast、dynamic_cast、const_cast、reinterpret_cast
static_cast
只要不包含底层const,都可以使用static_cast,常用于编译器无法自动执行类型转换时。
const_cast
只能改变运算对象的底层const,且不会改变对象本身的const属性,通常改变指针,且无法真正通过改变后的指针写入。
const int a = 5;
const int *p = &a;
int * q = const_cast<int *>(p);
cout<<*p<<endl;
reinterpret_cast
为运算对象的位模式提供较低层次上的重新解释
dynamic_cast
建议:尽量不要使用强制类型转换
总结
关于运算符的一些知识,主要是对运算顺序和sizeof以及强制类型转换有新收获