在讲下面的内容之前,要先看看这篇文章const、static变量的存储位置
一、C中的const
作用:(1)可以定义const常量,具有不可变性。
(2)便于进行类型检查,使编译器对处理内容有更多了解,消除了一些隐患。
(3)可以避免意义模糊的数字出现,同样可以很方便地进行参数的调整和修改。 同宏定义一样,可以做到不变则已,一变都变!
(4)可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。 还是上面的例子,如果在函数体内修改了i,编译器就会报错;
(5) 可以节省空间,避免不必要的内存分配。 例如:
#define PI 3.14159 //常量宏
const double Pi=3.14159; //此时并未将Pi放入RAM中 ......
double i=Pi; //此时为Pi分配内存,以后不再分配!
double I=PI; //编译期间进行宏替换,分配内存
double j=Pi; //没有内存分配
double J=PI; //再进行宏替换,又一次分配内存!
const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝。
①const变量与常量的区别
C中const变量是由编译器指定的只读数据,存储在只读数据区,但它不是常量,虽然常量也存储在只读数据区,所以不能由它来指定数组的长度。例如下面的是不允许的:
二、C++中的const
以上所讲内容在C++中同样适用,另外在C++中const经常用来限定成员函数类型,使其成为常成员函数。const成员函数应该在函数原型说明和函数定义中都增加const限定。
<pre class="cpp" name="code">#include<iostream> using namespace std; //const int Y; class C { const int X; int M; public: C(int a = 0,int b = 0):X(a),M(b){} int Get() const { return X; } //void Set() //{ // X = 5; //} int GetX() { return X; } //void SetX(int X) //{ // this->X=X; //} }; void main() { const C constC(5); C c; cout << constC.Get(); cout << c.Get(); cout << c.GetX(); //cout << constC.GetX(); }
①非常量成员函数不能被常量成员对象调用,因为它可能企图修改常量的数据成员,所以constC.GetX()将会产生错误。
②常量成员函数定义里面不能修改成员变量的值,所以C::Set()成员函数将会产生错误。
我们定义的类的成员函数中,常常有一些成员函数不改变类的数据成员,也就是说,这些函数是"只读"函数,而有一些函数要修改类数据成员的值。如果把不改变数据成员的函数都加上const关键字进行标识,显然,可提高程序的可读性。其实,它还能提高程序的可靠性,已定义成const的成员函数,一旦企图修改数据成员的值,则编译器按错误处理。
为了确保const对象的数据成员不会被改变,在C++中,const对象只能调用const成员函数。如果一个成员函数实际上没有对数据成员作任何形式的修改,但是它没有被const关键字限定的,也不能被常量对象调用。
③但构造函数和析构函数对这个规则例外,它们从不定义为常量成员,但可被常量对象调用(被自动调用),它们也能给常量的数据成员赋值。
注:在类中声明的const变量可以不用初始化,但是在其他情况下必须初始化。