一.定义常量
const修饰变量,以下两种定义形式在本质上是一样的
const TYPE ValueName = value;
TYPE const ValueName = value;
功能是对变量声明为只读特性,并保护变量值以防被修改。举例说明如下:
1 const int i = 5; //方式一 2 int const i = 5; //方式二 3 i = 10; //报错
上面这个例子表明,变量i具有只读特性,不能够被更改;若想对i重新赋值,如i = 10;则是错误的。
二.修饰指针
const修饰指针要特别注意,共有三种形式,一种是用来限定指向空间的值不能修改;另一种是限定指针不可更改,还有一种是限定两者都不能更改的。
1.char* const pContent;表示指针本身是常量不可变
2. const char *pContent;表示指针所指向的内容是常量不可变
3.const char* const pContent; 表示两者都不可变
例子:
int i = 5; int j = 6; int k = 7; const int * p1 = &i; //定义1 int * const p2 =&j; //定义2 *p1 = 20; //程序报错 p1 = &k; //可以通过 p2 = &k; //程序报错 *p2 = 80; //可以通过
在定义1中const限定的是*p1,即其指向空间的值不可改变,若改变其指向空间的值如*p1=20,则程序会报错;但p1的值是可以改变的,对p1重新赋值如p1=&k是没有任何问题的。
在定义2中const限定的是指针p2,若改变p2的值如p2=&k,程序将会报错;但*p2,即其所指向空间的值可以改变,如*p2=80是没有问题的,程序正常执行。
注意!有一个区分方法:
沿着*号划一条线:
如果const位于*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;
如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量。
三.函数中使用const
1.修饰函数参数
a.传递过来的参数在函数内不可以改变
void fun1(const int i) { //其它语句 …… i++; //对i的值进行了修改,程序报错 //其它语句 }
b.参数指针所指内容为常量不可变
void fun2(const int *p) { //其它语句 …… (*p)++; //对p指向空间的值进行了修改,程序报错 //其它语句 }
c.参数指针本身为常量不可变
void fun3(int * const p) { //其它语句 …… int i = 10; p = &i; //对p指针的值进行了修改,程序报错 //其它语句 }
d.参数为引用,为了增加效率同时防止修改。修饰引用参数,引用参数在函数内为常量不可变
void fun(A a); void fun(const A &a);
以上两种传值效果一模一样,但第一个函数效率低。函数体内产生A类型的临时对象用于复制参数a,临时对象的构造、复制、析构过程都将消耗时间。而第二个函数提高了效率。用“引用传递”不需要产生临时对象,节省了临时对象的构造、复制、析构过程消耗的时间。但只用引用有可能改变a,所以加上const。
2.const修饰函数返回值
const修饰函数返回值其实用的并不是很多,它的含义和const修饰普通变量以及指针的含义基本相同。
const int fun1(); const int * fun2(); int* const fun3(); int a = fun1() ;//这个其实无意义,因为参数返回本身就是赋值。 const int *b = fun2(); //我们可以把fun2()看作成一个变量,即指针内容不可变。 int * const c = fun3(); //我们可以把fun3()看作成一个变量,即指针本身不可变。
四.与类相关const的使用
1.const修饰成员变量
const修饰类的成员函数,表示成员常量,不能被修改,同时它只能在初始化列表中赋值。如下:
class A { … const int nValue; //成员常量不能被修改 … A(int x): nValue(x) { } ; //只能在初始化列表中赋值 }
2.const修饰成员函数
任何不会修改数据成员的函数都应用const修饰,这样,当不小心修改了数据成员或调用了非const成员函数时,编译器都会报错。const一般写在函数的最后来修饰。
class A { … void function()const; //常成员函数, 它不改变对象的成员变量. //也不能调用类中任何非const成员函数。 }
对于const类对象/指针/引用,只能调用类的const成员函数,因此,const修饰成员函数的最重要作用就是限制对于const对象的使用。
a. const成员函数不被允许修改它所在对象的任何一个数据成员。
b. const成员函数能够访问对象的const成员,而其他成员函数不可以。
3.const修饰类对象/对象指针/对象引用
const修饰类对象表示该对象为常量对象,其中的任何成员都不能被修改。对于对象指针和对象引用也是一样。
const修饰的对象,只能调用const成员函数,该对象的任何非const成员函数都不能被调用,因为任何非const成员函数会有修改成员变量的企图。
class AAA { void func1(); void func2() const; } const AAA aObj; aObj.func1(); //错误 aObj.func2(); //正确 const AAA* aObj = new AAA(); aObj-> func1(); //错误 aObj-> func2(); //正确
注:不是所有函数都能声明为const函数,例如构造函数和静态成员函数
对于构造函数:const修饰函数表示该函数的返回值是const类型的,改返回值只能赋值给同类型的const变量。
const是可以修饰类的成员函数,但是该函数不能修改数据成员。构造函数也属于类的成员函数,但是构造函数是要修改类的成员变量,所以类的构造函数不能申明成const类型的。
对于静态成员函数:static静态成员是属于类的,而不属于某个具体的对象,所有的对象共用static成员。this指针是某个具体对象的地址,因此static成员函数没有this指针。而函数中的const其实就是用来修饰this指针的,意味this指向的内容不可变,所以const不能用来修饰static成员函数。
以上就是我对C++中const的理解,第一次发博客,难免有疏漏,如有错误,请批评指正!!!也欢迎大家与我一起学习交流!
参考资料:Eric_Jo的文章