C++ const用法

本文记录了C++中const的使用方法。const可限定变量或函数某些地方不可改变,定义时须赋值,在单文件有效,多文件需加extern。还介绍了const在引用、指针、函数参数、成员函数和返回值等方面的应用,强调编程中应多用const以提高代码健壮性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

c++ const学过多次了,但碰到工程代码还是不熟练。参考了其他博客,在此记录下来,以便有需要时翻看。
限定符const的作用是让变量或函数的某些地方不能改变。

const基础知识

  • const在定义时候必须赋值
const int i=0; //i不能改变数值,且定义的时候必须初始化
i=1; //会报错,常量不能改变值
const int j; //报错,没初始化
//初始化方法没太大限制,可以用其他变量初始化
  • const只在单个文件中有效,若想在全部文件中有效需要加extern
// 在.cc中定义并初始化了一个常量,该常量能被其他文件访问
extern const int i=0;
// .h头文件
extern const int i;
  • 利用一个对象去初始化另外一个对象,则它们是不是const都无关紧要。(但是引用和指针有限制)
int i=42;
const int ci=i;用变量初始化常量
int j=ci;用常量初始化变量

const的引用

常量的引用是指变量或者常量绑定到const对象上。

可以将常量赋给常量的引用,但不能把常量赋给变量的引用。即,左边为const int &i=右边变量和常量都可以。但不可int &=const int,因为这样可能改变值。

const int ci=1024;
const int &r1=ci;//正确,把常量赋给常量的引用
r1=42; //错误,r1是对变量的引用,不能变值
int &r2=ci;//错误,不能把常量赋给变量的引用

指针和const

  • 不能把常量的地址赋给变量的指针。
const double pi=3.14;
double *pter=π//错误,不能把常量的地址赋给普通指针
const double *cptr=π//正确。此处是常量数据,非常量指针,即常量是不能找到其地址进行改变值的
*cptr=42;//错误,不能给*cptr赋值,
const指针

常量指针必须初始化,即常量的东西必须初始化

把*放const之前说明指针是常量,即不变的是指针本身的值,而非指向的那个值。

顶层cosnt,底层const

顶层const:指针本身个常量,作用于对象本身,意思是如果是指针的话那么对象是指针。例:int *const p1=&i;

底层const:指针所指的对象是一个常量。

int i = 0;
int *const p1=&i;//不能改变p1的值,是一个顶层const
const int ci=42;//不能改变ci的值,是一个顶层const
const int *p2=&ci;//允许改变p2的值,是一个底层const。int* cosnt p是顶层的
const int *const p3=p2;//靠右的const是顶层const,靠左的是底层const
const int &r=ci;//用于声明引用的const都是底层const

拷贝操作时,顶层const不受什么影响。
i=ci;//ci是一个顶层const,对此操作无影响
p2=p3;//p3顶层const的部分不影响

但底层const拷贝时,拷入和拷出的对象必须具有相同的底层const资格。
一般来说,非常量可以转换成常量,反之则不行
int *p=p3;//错误,p3包含底层const的定义,而p没有
p2=p3;//正确,p2和p3都是底层const
p2=&i;//正确,int*能转换成const int*
int &r=ci;//错误,普通的int&不能绑定到int常量上
const int &r2=i;//正确,const int &可以绑定到一个普通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
    int * a5 = *a2;   //报错,不能把常量地址赋给变量的指针
    const int * a4 = &a1;   ///const data,non-const pointer,
    const在*之前,常量数据,非常量指针。【可以记为哪个在前哪个优先级高,只适用于一const一指针的情况】
    
    int * const a5 = &a1;   ///non-const data,const pointer,只能
    // *在const之前,非常量数据,常量指针。常量指针必须初始化
        
    
    //常量数据,常量指针,下面两种方法等效,*左右各2个单词
    int const * const a6 = &a1;   ///const data,const pointer
    const int * const a7 = &a1;   ///const data,const pointer
    return 0;
}

const修饰函数参数

代表传递过来的参数在函数内不可以改变。

void testModifyConst(const int _x) {
    _x=5;   ///编译出错
}

const修饰成员函数:形参后、函数体前加const

(1)const修饰的成员函数不能修改任何的成员变量(mutable修饰的变量除外)

(2)const成员函数不能调用非const成员函数,因为非const成员函数可以会修改成员变量

#include <iostream>
using namespace std;
class Point{
    public :
    Point(int _x):x(_x){}
    void testConstFunction(int _x) const{

        ///错误,在const成员函数中,不能修改任何类成员变量
        x=_x;

        ///错误,const成员函数不能调用非const成员函数,因为非const成员函数可以会修改成员变量
        modify_x(_x);
    }

    void modify_x(int _x){
        x=_x;
    }
    int x;
};

const修饰函数返回值

(1)指针传递

如果返回const data,non-const pointer,返回值也必须赋给const data,non-const pointer。因为指针指向的数据是常量不能修改。

const int * mallocA(){  ///const data,non-const pointer
    int *a=new int(2);
    return a;
}

int main()
{
    const int *a = mallocA();
    ///int *b = mallocA();  ///编译错误
    return 0;
}

(2)值传递

如果函数返回值采用“值传递方式”,由于函数会把返回值复制到外部临时的存储单元中,加const 修饰没有任何价值。

所以,对于值传递来说,加const没有太多意义。

所以:

不要把函数int GetInt(void) 写成const int GetInt(void)。

不要把函数A GetA(void) 写成const A GetA(void),其中A 为用户自定义的数据类型。

在编程中要尽可能多的使用const,这样可以获得编译器的帮助,以便写出健壮性的代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值