C++ const 、constexpr修饰用法

const 修饰用法

const 的用法  一句话:限定某个内容对应的值不可以被改变(是常量,不可再次被赋值!)

在C++11之前,有两个功能。

修饰常量   :定义变量时使用  把变量变为常量

变量只读   :函数形参处使用   表示形参为只读变量

这两者是有差别的!!!!!!

1 、const 于变量

1.1 int const 与const int

int const a = 100;
const int a = 100; //与上面等价
int const arr [3] = {1,2,3};
const int arr [3] = {1,2,3};//与上面等价

  const 在数据类型 int 的左侧和在右侧是一样的 

另外,int 也可以看做是一种类,a可以看做是对象。所以,const也可以修饰对象和结构体等数据

  1.2 const修饰后成为常量,不可以再次被复制

int c1=10;int c2=20;
const int *p1=&c1;//p1对应的地址,其地址空间里的数据值固定
qDebug()<<"*p1="<<*p1<<endl;//输出值 10
*p1=c2;//error 
p1=&c2;//改变地址,地址对应的值也就变了
qDebug()<<"*p1="<<*p1<<endl;//输出值 20 
*p1=30;//error  
//总之   *p1=常量  就是不被允许的

//*p=30;本质上是想改变地址空间里存储的数据值

总之   *p1=常量  的赋值操作 就是不被允许的

const int num =10;num=20;是错的。此时num是常量!是常量!是常量!10=20;这样的语句显然错误

同理  const int *p=&num;之后,无论p里面存储的地址值是多少,*p的值可以随地址改变而改变,但*p的结合 依旧是常量,不可再次被赋值。 *p=20;是错误的。

2.const 于指针变量(地址)

int a = 5; int b = 10;
int *const p = &a;
*p = 20;     //right 可以修改所指向变量的值
 p = &b;      //error 不可以指向别的变量

此时 p与变量a的地址绑定,

3. const修饰函数

const 在函数中根据修饰的位置分为三种:函数参数、函数返回值、成员函数。

const  int fun (const int a) const;

 3.1 const 修饰 函数参数  

 3.1.1防止传入的变量被函数改变 比如指针的指向(地址存储的值)

char a='A',b='B';
char *str1=&a; char *str2=&b;
void stringCopy(char* strDest, const char* strSource);//函数声明
 StringCopy(str1, str2);//函数调用 *str1 的值可以被函数改变  *str2的不能被改变
/*
 此时 发生形参初始化的动作 char* strDest= str1;const char* strSource=str2;
 strDest与 str1 对应的地址相同  strSource与str2
 如果函数里面发生 * strDest='C';//操作合法,但是上面的*str1 的值发生了改变 即a='C'
 如果函数里面发生 * strsOURSE='D';//操作报错  *str2的值,在函数里面改不了
*/

 注意:const char* strSource作形参 之后,* strSource就不能再被赋值了,即不能被修改了。可以使用传入参数的值,但不能改变输入参数的值。防止传入值被函数改变

 3.1.2修饰函数参数  传入值的问题

int add1(int& a, int& b){ //非const引用只能接受 变量,不能接受const类型的参数
    return a + b;
}
int add2(const int & a, const int &b){
    return a + b;
}
int main(int argc, const char * argv[]) {
    int _a = 3;
    const int _b = 5;
    int _c = 4;

    add1(_a,_a);//传入非const参数可以
    add1(_a,_b);//传入const参数报错
    cout << add2(_a,_b) <<endl;//const类型参数可以传入
    cout << add2(_a,_c) <<endl;//非const类型参数可以传入
}

 注意:const in  &b作形参 之后,b就不能再被赋值了,是只读变量,即不能被修改了。可以使用传入参数的值,但不能改变输入参数的值。防止传入值被函数改变

 3.2 const 修饰 成员函数  即 函数尾部的 const 

class MyClass {
public:
    void func(int x) const;
};

注意:const 放在函数尾部  这种情况仅限于函数是成员函数  !!!其它函数没这种修饰

1) const 成员函数与对象、函数、成员变量之间的关系

总结就是:

const 对象通过对象调用只能显式访问const 成员函数;非const 对象能所有显式成员函数;

const 成员函数能读取所有成员变量,但都不能修改它们;

const 成员函数只能访问const 成员函数,但能被其它任何成员函数访问;

const 修饰的成员函数为了保护成员变量,要求const 函数不能修改成员变量,否则编译会报错,除非变量用mutable修饰。

2) 函数尾部的const与函数重载:

函数尾部的有无const可以作为重载条件。例如,常对象调用同名函数时,一定是调用const函数。

需要注意的是,常对象的成员函数(除了常量成员函数)默认是不能修改成员变量的,因为被声明为常对象的成员函数是隐式的const函数。如果在成员函数内部需要修改成员变量,可以使用mutable关键字修饰相应的成员变量。

3.3 const 放在函数前 

使用较少,略。

4.const 与引用

4.1普通变量的引用加const

int num =2;
const int& b=num;
num=3;
//b=4;//错误
cout<<"b="<<num<<endl;//b值为3

 常引用必须在定义时,就初始化

const int& b;//错误,没初始化
b=4;//错误,不可再赋值

2023-07-16更新,未完待续,优化中……

const关键字的作用很多,这里只解释它作为函数形参的一个作用,主要有两个作用:

(1)它告诉编译器,这个参数是一个常量,首先你在函数内部不能改变它;

(2)其次,如果在函数内部需要多次引用这个值,CPU不必每次都重新读取,直接使用第一次读取的值(我想应该是存放在寄存器文件中的)。

常量表达式函数

使用constexpr修饰函数的返回值,这种函数被称为常量表达式函数。这些函数主要有以下几种:

普通函数

类的成员函数

类的构造函数

成员变量a变成了常量,不可再给它赋值了

模板函数 (函数模板是模板,如下面的10-13行。模板函数是函数模板定义出来的函数19,23行)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值