2013年一月份在别的地方写的博客,现在搬过来。回头看看,那时候的文风还真是有趣呢~
《C++ Primer》这本书带看不看的好多年了。每过一段时间,就拿出来看看。书都折胶了。常看的章节也都泛黄了。但是很多细小但是很重要的点仍然记不住。总是翻看时记得很清楚,但是过一段时间就模糊了。以前总是想把这本厚得跟转头一样的书的要点整理出来,弄成一个很薄很薄的内容。这样每过一段时间就翻出来看看,容易复习。
最近想,为何不整理在微博里呢?这样共享出来,还能给朋友们一起看看。当然,看这些内容的人,我希望你还是要有点相关知识的基础的。因为我不会从零开始。如果没看过《C++ Primer》,就得自己先看看了。
好吧,第一次废话比较多。今天咱们就聊一聊关键字const
。
const
,大家都知道,表示这个量是个常量,不能变化。也就是说,凡是用它修饰的东西,必须在声明的时候给它初始化,不然这个东西(就是常量)就再也没有被改变的机会了。比如:
const int MAXNUM = 100;
这就表明,MAXNUM
在它活在世上这一辈子里(就是生命周期中),就只能是100了。从生到死,始终表里如一,平静如水,毫无变化。
这很简单吧?原本一切都是这么简单,这么美好。但是当const
遇到别的东西的时候,一切都开始复杂了,开始让人捉摸不定,让人困惑。就好比人生,自己一个人总是很简单,当你开始恋爱了,有家庭了,有孩子了,一切都变了。就连生活习惯都可能改变了!
一、当简单明了的const
遇到万恶的指针,注定会产生峰回路转、曲折离奇的爱情故事
指针,万恶之源。产品里很多的bug,都是来源于指针。什么指针没释放,导致内存溢出啊;什么指针还需要使用,指向的内存空间就被释放了啊。有人说C++和C难学难用的原因之一,就是因为要自己管理指针。这话有点道理。
那么如果const
爱上指针,会产生什么呢?可能大家张嘴就能说,当然是“const
类型的指针”和“指向const
类型的指针”啦!
不过,可能令你很惊讶的是:const
和指针之间的体位却有三种!看下面的code:
int a = 1;
int b = 2;
int c = 3;
int d = 4;
int const* p1 = &a;
const int* p2 = &b;
int* const p3 = &c;
你可能会想:为什么会有三种呢?亲!不是只有两种结果吗?这不是真的,p1
、p2
、p3
当中一定有一个是错误的结合!
我告诉你,这三种都是他们合法的爱情的结晶。另外,谁告诉你,相同的结果只能有一种表达方式了?比如无论 是西红柿炒鸡蛋,还是鸡蛋炒西红柿,还是番茄鸡蛋,这都是一样一样一样的啊!亲!
p1
和p2
其实是一样的!都是指向const类型的指针,也就是说,不能通过p1
和p2
,来分别改变a
和b
的值。不过,庆幸的是,p1
和p2
在指向一个对象以后,不一定非得一棵树上吊死,它俩还可以指向别的对象。就好像,如果你结婚后对方不能带给你幸福,而自己又无法改变对方。那么,看完这个类型的指针,你就知道了,都什么年代了!你可以离婚去追求自己的幸福啊,亲!
p3
是const
类型的指针。它一旦指向某一个对象,那么这辈子就只能指向它了。正所谓嫁鸡随鸡,嫁狗随狗。忠贞不二!这是中国男人心目中的好老婆。当然,p3
也是好指针。当你和一个老外交谈,说到一个比较好的观点时,对方往往会说,good point!什么意思呢?就是good pointer的口语简化,就是“好指针”的意思!
不过,p3
如果看对方不爽,可以改变它!此时,我的脑海里浮现出很多别人老婆的光辉形象,比如俞敏洪的老婆啊,李彦宏的老婆啊。这些老婆们,都是good point!
正所谓龙生九子,各有不同。p1
、p2
、p3
这哥仨,经过const
和指针的杂交,在外形和功能上至少有一方面不同,那么我们到底怎么区分呢?
把const
想成老婆,把int
(或者别的变量类型)想成第三者,那么老婆和你站在同一边的,也就是都在* 号右边的,远离第三者的,就是同甘共苦,荣辱与共,也就是我们所说的好老婆,就是const
类型的指针;而老婆和你在* 号两边的,离第三者总比离你近的呢?就是属于同床异梦的,就是指向const
类型的指针。正所谓夫妻本是同林鸟,大难临头各自飞。p1
和p2
的日子不好过啊。
如果我说这么形象你还记不住,那么……记得常喝六个核桃!
二、三个孩子还有故事
简单说说这仨倒霉孩子。
1.孩子们的指向到底有没有问题?
指向const
类型的指针,也就是p1
和p2
,一般是用来指向const
类型的对象的。这本无可厚非。但是,他们可不可以指向非const
类型的对象呢?
答案是:可以滴!
不过,我们仍然不能通过这类指针去改变他们所指向的对象的值。为什么呢?原因就是p1和p2这哥俩天生就有缺陷。只要让他们指向了,看谁都是const
类型的对象!可悲吗?
所以夫妻生活一定要幸福,不然生下来的小孩都不健康哦~
那么,大家很快会想到p3
了。const
类型的指针呢?const
类型的指针可以指向非const
类型的对象,但是它坚决不会去指向const
类型的对象。因为,它知道,它是要改变对方的,如果对方不向它敞开心扉,它干脆放弃。
顺便说一句,void*
指针不能用来指向const类型对象,必须用const void*
。
2.偶尔有别的东西出来客串,再脑残也是要交朋友的!
再来看看这个code:
typedef int *intPoint;
const intPoint p5;
那么p5到底是“const
类型的指针”还是“指向const
类型的指针”?
大家一定会说p5
是“指向const
类型的指针”。嗯,但是错了!哈哈!其实人家p5
是“const
类型的指针”呢~
为什么呢?估计大家是内联的展开了intPoint
。其实也没错。但是不管怎样,intPoint
始终是个指针,那么const
修饰指针,那当然是“const
类型的指针”啦!
三、还有一个私生子,嘘~能不说就不说吧!
看下面的code:
int d = 4;
const int* const p4 = &d;
这种指针很少露面。一般都隐匿起来。为什么呢?因为这个是“指向const类型的const指针”。这类指针,一旦初始化之后,既不能通过它改变指向类型的值,也不能指向别的指针。所以基本上就是个废物,出场率不高。
想想吧,同时娶两个老婆(const
),在新中国已经不允许了!虽然很多男人都想这样……
四、当const
为函数打工,小秘和老板之间总有无限引人遐想的故事
一个类里的成员函数,它不想改变类里的任何成员变量。但是它自己没有这个自制力,所以想找人来管管。于是乎,它找到了const
。看这一段code,这是一个定义在类Sales_item
外面的成员函数,摘自《C++ Primer》第四版:
double Sales_item::avg_price() const
{ if (units_sold)
return revenue/units_sold;
else
return 0;
}
avg_price()
没有改变任何的成员变量,事实上,它想改也改不了。一切都在const的严格控制当中。const的限定非常严格,我猜它是处女座的!
当然,我们只有const
成员函数。如果不在类里,就没有const
函数。你可以把在类里的函数想象成在体制内的部门。这种部门总是约束这约束那,所以得有const
。但是体制外的,社会闲杂人等,不需要什么约束。
五、结束语
说了这么多,有可能有遗漏的。毕竟关于const
,总是有说不完的话题。但是基本万变不离其中吧。运用基本知识,解决复杂问题。如果以后真有什么我觉得可以补充的,再开博客再详谈吧。
真佩服那些有毅力的人,能从头看到这里。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。