C++ const 总结

C++ const 允许指定一个语义约束,编译器会强制实施这个约束,允许程序员告诉编译器某值是保持不变的。如果在编程中确实有某个值保持不变,就应该明确使用const,可以减少奇怪的BUG。

1. 修饰普通成员变量

对于指针和引用类型,const一般分为顶层const和底层const。顶层const就是表示自己本身是常量,不能改变。底层const就是表示自己所引用的或指向的是常量,不能改变自己指向或引用的对象的值。

从上面就可以知道,对于一般类型(非指针或引用), 如int, const指的就是顶层引用了,表示自己是常量,因为他们不能指向或引用别人。

对于一般的const用法在此就不再阐述,这里以const 修饰指针为例,修饰引用与此大致相同。

#include<iostream>
using namespace std;
int main(){
    int a1=3;   ///non-const data
    const int a2=a1;    ///const data

    int * a3 = &a1;   ///non-const data,non-const pointer
    const int * a4 = &a1;   ///const data,non-const pointer
    int * const a5 = &a1;   ///non-const data,const pointer
    a5 = &a2; //error
    *a4 = 13; //error
    int const * const a6 = &a1;   ///const data,const pointer
    const int * const a7 = &a1;   ///const data,const pointer

    int * const a8 = &a2; //error,a8 points to non-const data and a2 is const
    const int * a9 = &a2;
    //*a9 = 10;
    
    return 0;
}

示例的代码如上。总结,const修饰指针时,

  1. 位于 * 左边的是底层const,如 const int *,也就是表示指针所指数据是常量,不能通过解引用修改该数据;但是指针本身是变量,可以指向其他的内存单元。
  2. 位于 * 右边的是顶层const,如 int * const,也就是表示指针本身是常量,不能修改指针本身的指向。
  3. 当左右都有 const 时, 聪明的读者可能已经知道了,这时上述两个特点都具备,也就是指针本身是常量,指针指向的也是常量。

可能有人会记住这么复杂的规则,在这里介绍个小技巧,可以轻松记住。首先以 * 为分隔符,* 号 右边的 const 因为离 指针名近,所以它表示的是指针本身的const状态,为顶层const。 * 左边的const 离变量名远,所以他表示的是指向的对象的const状态,为底层const。

同时,从上述代码 a8 可以看出,a8所指向的a2是const 类型,所以 a8 的类型应该有一个底层const,代表它指向的是常量数据,底层const位于 * 左边,所以 a8 的类型可以是 const int * 或者 const int * const。在示例代码中a8的类型是int * const, 没有底层const,所以会报错。

2. const修饰函数参数

传递过来的参数在函数内不可以改变,与上面修饰变量时的性质一样。

void testModifyConst(const int _x) {
     _x=5;   ///error
}

 

3. const 修饰函数

class example{
    public:
        int a;
        void test(int *p) const{
            *p = 5;  // ok
            a = 1;   // error
        }
};

注意:const 修饰函数只能用来修饰成员函数,不能是不在类里面的普通函数,同样也不能是类的静态函数,下面会讲这样的原因。非静态的成员函数中都会有一个默认的 this 指针,指向一个实例,this指针默认是 <classname> * const this, 即 改变this的指向,加上 const 关键字之后 会给 this 指针 加一个底层const,即 this指针的类型变为 const <classname> * const this, 意味着不能通过 this 指针 去修改实例的属性。这里隐藏的一个知识点是实例的访问其实都是通过this指针访问的,如上所示 a = 1 这条语句 其实 是 this-> a = 1; 只是编译器替我们做好了这一部分工作。

此外,在写成员函数时一定要考虑是否要加const,不加const 意味着这个成员函数将无法应用于const 类型的实例,因为此时的this 指针类型是 <classname> * const this,而入的实例类型是 const <classname> a, 转换后的this指针类型是const <classname> * const this, 两者无法直接转换。所以要考虑这个成员函数是否需要作用在 const实例上 以及函数内部是否需要修改属性。

4. const 修饰函数返回值

待补充

 

参考资料:C++ const用法 尽可能使用const

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值