C++关键字—Const

一、Const修饰指针

int b=100;
const int *a=&b;  //情况一
int const *a=&b;  //情况二
int*const  a=&b; //情况三
const int*const a=&b;  //情况四

判断标准:

  • 如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;
  • 如果const位于星号得右侧,const就是修饰指针本身,即指针本身是常量。

1、情况一

如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量。

因此,1和2情况相同,都是指针所指向的内容为常量(与变量声明符的位置无关),这种情况下不允许对内容进行更改操作。

举个例子,如果a是一名仓库管理员的话,他所管理的仓库,里面的货物(*a)是他没有权限更改的,仓库里的东西是什么就一直是什么。因此 :


 int  b=100const int*a=&b;
 *a=200;  //错误

怎么改变值:

  • 代打。自己不去改变,但别人可改变,可以让别人去呀,最终值也是改变了;
  • 换工作。自己不想干当下得了,换个工作嘛,从新指向一个新的值。

代打是什么意思了?首先回顾下指向常量的指针是什么意思。

所谓的指向常量的指针仅仅要求的是,不能通过该指针改变对象的值,没有规定此对象的值不能通过其他途径更改。自己不干坏事,但是别人你管不了啊。

也可以这样想:所谓指向常量的指针或引用,不过是指针或引用“自以为是”罢了,它们是好人,不做坏事。他们觉得指向了常量,所以自觉地不去改变所指对象的值。

因此想改变*a的值,可以这样:

int b=100;
const int *a=&b;
b=200;
cout<<*a<<endl;  //得到200

换工作。要想改变*a的值还有一种方式,因为当前情况为指针指向的为常量,也就是说你指向的东西不能改变,但不代表你不能指向其它对象呀。

如果你觉得管理水果这活太累,你可以去管理蔬菜嘛,换一个仓库不就行了。
int b=100,c=200;
const int *a=&b;
a=&c;
cout<<*a<

2、情况二

情况二与情况一相同。

3、情况三

如果const位于星号得右侧,const就是修饰指针本身,即指针本身是常量。

指针本身为常量,不能对指针本身进行更改操作。

    int b = 100,c=200;
    int *const a = &b;
    a = &c; //错误
    cout << *a << endl;

举个例子,a是一名仓库管理员,分配他看守一个仓库,那就是终身制得了,他就只能控制这个仓库,要是去管其他仓库就是错误的,因此a++这种操作也是错误的;

但是,对于仓库里的东西,他是可以随便换的,想放水果就放水果,想放蔬菜就放蔬菜,(*a=200这种更改操作是允许的)。

4、情况四

指针本身和所指向的内容均为常量。

    int b = 100,c=200;
    const int *const a = &b;
    a = &c; //错误
    *a = 200;  //错误
    cout << *a << endl;

a还是仓库管理员,这个时候,他就是地地道道的看门的了,一点权力都没有,他不能换工作,也不能动仓库里的东西。

二、函数中使用Const

1、const成员函数

一般形如:

void fun()  const  {}

我们定义的类的成员中,如果是不改变类的数据成员的成员函数,我们就用Const关键字进行标示。它不仅可以提高程序的可读性,还能提高程序的可靠性,当你企图更改数据成员时,编译器会按错误处理。

2、用const修饰函数返回值

如果给以“指针传递”方式的函数返回值加const修饰,那么函数返回值(即指针)的内容不能被修改,改返回值只能被赋给加const修饰的同类型指针。

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
using namespace std;

class Base{
private:
    int x;
    char *p;
public:
    Base(void){
        x=0;
        p=(char *)malloc(sizeof(10));
        strcpy(p,"123456");
    }
    void Set_x(int tx){
        x=tx;
    }

    //函数名后面加const表示这个对象指针this所指之物是无法改变的
    int Get_x()const{
        //x++;这样编译报错
        return x;
    }

    //返回值是指针类型
    const char* ret_p(){
        return p;
    }
};

int main(){
    Base a=Base();
    printf("%d\n",a.Get_x());

    //char* y=a.ret_p(); 这样编译会出错,需要const 修饰的
    const char* y=a.ret_p();
    printf("%s\n",y);
}

3、const修饰函数参数

如果参数做输出作用,不论采用什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加const修饰,否则该参数将失去输出功能,const只能修饰输入参数。

1)输入参数采用“指针传递”

输入参数采用“指针传递”,那么const修饰可以防止意外改动改指针,起到保护作用。
例如:

void func(char *strDes,char *strSource);

其中strDes是输出参数,strSource是输入参数,如果函数中试图修改strSource的内容,编译器会报错。

2)输入参数采用“值传递”

输入参数采用“值传递”,函数将自动复制一个该参数的临时变量,输入参数无需保护,不需要加const修饰。

3)输入参数采用“引用传递”

如果A是我们自定义的一个数据类型,也就是非内部数据类型,当我们按照值传递的方式传递参数参数时,效率将非常低下。因为函数将复制一个该参数的临时变量,而临时变量的构造、复制、析构都很消耗时间。

为了提高效率我们可以将采用“引用传递”,形如;void Func(A&a),引用传递传的是地址不需要复制参数。
但是正因为传的是地址,又存在一个隐患,参数的值有可能被我们改变。

为了解决这个问题,我们需要加上const修饰参数,因此函数最终成为void Func(const A&a);这是参数是非内部数据类型的情况,如果参数是内部类型,那就不用采用引用传递了,直接值传递就可以了,因为内部数据类型不存在构造、析构的过程,复制也很快。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值