c++中const的用法

一.定义常量

 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的文章

posted @ 2020-09-09 13:48  wmbilibili  阅读(370)  评论(0编辑  收藏  举报