const_learning2
Updated:
采用符号常量写出的代码更容易维护;const最常见的用途是作为数组的界和switch分组标号。分类如下:
- 常变量:const 类型说明符 变量名
- 常引用:const 类型说明符 &引用名
- 常对象:类名 const 对象名
- 常成员函数:类名::func(形参) const
- 常数组:类型说明符 const 数组名[大小]
- 常指针:const 类型说明符 指针名,类型说明符 const 指针名
常量
取代了C语言中的宏定义,声明时必须进行初始化(C++中则不然)。const限制了常量的使用方式,并没有描述常量应该如何分配。
用const声明的变量虽然增加了内存,但是可以保证类型的安全。
指针与常量
使用指针涉及到两个对象:该指针和它所指的对象,const char *p = greeting;
//指针可以改变,但是指针指向的数据不能改变。char* const p = greeting;
//指针不能改变,但是指针指向的数据可以改变。
const修饰函数的传入的参数
将函数传入的参数声明为const,以指明这种参数仅仅是为了效率的原因,同理,将指针参数声明为const,函数将不能修改这个参数所指向的对象。
修饰函数返回值
可以修改用户修改返回值。返回值也要相应的付给一个常量和常指针。
const修饰成员函数
const_learning中已经讲述过。
展开来讲:
常量与指针
- 对于常量指针,不能通过该指针改变它所指的内容。
|
|
这样是会报错的。
- 但是,可以使用另外一个指针来修改。
|
|
实际上,在将程序载入内存的时候,会有专门的一块内存区域来存放常量。但是,上面的i 本身不是常量,是存放在栈或者堆中的。我们仍然可以修改它的值。而pi 不能修改指向的值应该说是编译器的一个限制。
常量与引用
常量与引用的关系稍微简单一点。因为引用就是另一个变量的别名,它本身就是一个常量。也就是说不能再让一个引用成为另外一个变量的别名, 那么他们只剩下代表的内存区域是否可变。int i = 10;
//正确:表示不能通过引用修改对应的内存的内容const int& ri = i;
//错误!不能这么写int& const rci = i
有必要深入的说明以下,在系统加载程序的时候,系统会将内存分为4 个区域:堆区 栈区全局区(静态)和代码区
。从这里可以看出,对于常量来说,系统没有划定专门的区域来保护其中的数据不能被更改。也就是说,使用常量的方式对数据进行保护是通过编译器作语法限制来实现的
。我们仍然可以绕过编译器的限制去修改被定义为“常量”的内存区域。
C++ 中的const
const常量
const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查
const 修饰类的数据成员。
const 可以提供封装特性,可以修饰类的数据成员。- 不同的对象其const 数据成员的值可以不同。所以不能在类声明中初始化const 数据成员,因为类的对象未被创建时,编译器不知道const 数据成员的值是什么。
|
|
- const 数据成员的初始化只能在
类的构造函数的初始化表
中进行。要想建立在整个类中都恒定的常量,可以采用所谓的“ the enum hack”的补偿的做法。其理论的基础是:“一个属于枚举类型(enumerated type)的数值可权当 ints 使用”
上述代码可以修改为:
|
|
枚举常量不会占用对象的存储空间,他们在编译时被全部求值。但是枚举常量的隐含数据类型是整数,其最大值有限,且不能表示浮点数。