我在C++:18篇里说过const的用法,这里我有必要再提升进阶下const的理解。
因为你可能只知道他是怎么用的,但是他为什么这样用,其他用法呢?
首先回顾下const有什么主要的作用?
(1)可以定义const常量,具有不可变性。
(2)便于进行类型检查,使编译器对处理内容有更多了解,消除了一些隐患。
(3)可以避免意义模糊的数字出现,同样可以很方便地进行参数的调整和修改。同宏定义一样,可以做到不变则已,一变都变
(4)可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。
(5) 为函数重载提供了一个参考。
(6) 可以节省空间,避免不必要的内存分配。例如:
#define PI 3.14159 //常量宏
const doulbe Pi=3.14159; //此时并未将Pi放入ROM中 ......
double i=Pi; //此时为Pi分配内存,以后不再分配!
double I=PI; //编译期间进行宏替换,分配内存
double j=Pi; //没有内存分配
double J=PI; //再进行宏替换,又一次分配内存!
const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝。
(7) 提高了效率。编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
常量与数组的组合有什么特殊吗? 我们给出下面的代码:
有什么问题吗?对了,编译通不过!为什么呢?
const可以用于集合,但编译器不能把一个集合存放在它的符号表里,所以必须分配内存。在这种情况下,const意味着“不能改变的一块存储”。然而,其值在编译时不能被使用,因为编译器在编译时不需要知道存储的内容。自然,作为数组的大小就不行了。
在函数中声明的形参,在函数被调用时会得到实参的值。但是如果在类中呢?
当直接用这个类定义一个对象时,会出错,提示没有初始化const成员变量值 且提示ci是一个只读的变量,const用于类中成员变量时,将类成员变为只读属性(只读:不能出现在“=”的左边,但在类中仍可以用一个指针来修改其值。) 所以不可以直接在类的构造函数中初始化const 的成员。
const成员变量只可以初始化列表中初始化
你再看看下面的例子:
vc6下编译通不过,为什么呢
this指针是不是const类型的?
this指针是一个很重要的概念,那该如何理解她呢?也许这个话题太大了,那我们缩小一些:this指针是个什么类型的?这要看具体情况:如果在非const成员函数中,this指针只是一个类类型的;如果在const成员函数中,this指针是一个const类类型的;如果在volatile成员函数中,this指针就是一个volatile类类型的。怎么理解,卖个关子,我将在下一篇文章解释。
const到底是不是一个重载的参考对象?
先看一下下面的例子:
上面是函数重载是没有问题的了,那么下面的呢?
这个是错误的,编译通不过。那么是不是说明内部参数的const不予重载呢?再看下面的例子:
这个程序是正确的,看来上面的结论是错误的。
为什么会这样呢?这要涉及到接口的透明度问题。按值传递时,对用户而言,这是透明的,用户不知道函数对形参做了什么手脚,在这种情况下进行重载是没有意义的,所以规定不能重载!当指针或引用被引入时,用户就会对函数的操作有了一定的了解,不再是透明的了,这时重载是有意义的,所以规定可以重载。
什么情况下为const分配内存?
以下是我想到的可能情况,当然,有的编译器进行了优化,可能不分配内存。
A、作为非静态的类成员时;
B、用于集合时;
C、被取地址时;
D、在main函数体内部通过函数来获得值时;
E、const的 class或struct有用户定义的构造函数、析构函数或基类时;。
F、当const的长度比计算机字长还长时;
G、参数中的const;
H、使用了extern时。
与static搭配会不会有问题?假设有一个类:
我们发现编译器会报错,因为在这种情况下static不能够与const共存!为什么呢?因为static没有this指针,但是const修饰this指针,所以...
要点: 对于优化做的比较好的编译器,代码const int i = 1;
当后面用到变量i 的时候,编译器会优化掉对i 的存取,而直接使用立即数1
读到这里的粉丝可能觉得我这个人比较变态,总喜欢写一些奇奇怪怪的代码来折腾人,没错,真正的游戏线上环境是复杂而且残酷的,必须得这么折腾才能长记性,最后我再折腾下各位,请看如下代码:
为什么i和*(int*)&i的结果不一样,二者有什么区别?欢迎留言哈,我将统一解答