C++中const完全详解
发布日期:2021-06-29 07:20:53 浏览次数:2 分类:技术文章

本文共 2406 字,大约阅读时间需要 8 分钟。

Const的定义在C++中十分繁琐复杂,因此令人十分头疼,非常的恶心。今天特意总结一下,从简单到难,逐步深入,目的是加深记忆,让这部分内容彻底不要成为心目中的难点:


一、最简单的赋值问题

const int a;//错误,常量必须初始化const int b=3;//正确int c=3;const int d=c;//正确

不用解释,一看就懂。

二、const的“引用”难点

从“引用”开始,const就出现了一些难点。

先说普通的引用。C++中有两种引用,左值引用和右值引用,右值引用是C++11中新增的这里不提,主要说左值引用,即:

int a=1024;int &b=a;

这之后,a和b就绑定在一起了,一荣俱荣,一损俱损。引用类型的初始值必须是一个对象,也就是说:

int &c=1024; //这是不对的,因为1024就是一个数字

除此之外,大部分情况下引用的类型和与之绑定的对象的类型应该严格匹配。也就是说,&b=a,那么a和b应该是同一种类型。

然而,在两种情况下,存在特例

1.存在继承关系的类。比如,我们可以把一个基类的引用,绑定到该基类的派生类上。这个我们不细说。

2.也就是出现const的时候。下面进行详解。

先说我们容易理解的情况,即类型相同可以引用,不同不能引用:

const int a=1024;const int &b=a; //正确,一个int常量引用另一个int常量,没毛病

在上面的基础上: 

b=10;//不对,因为b是对于常量a的引用,a已经定义成了1024,不能再改变。int &c=a;//也不对,因为c是非常量的int,不能引用常量a

也就是说对“非常量”来说,不能引用不相同类型的变量。

但如果对于一个常量来说,却可以引用“非常量”:

int i=10;const int &aa= i; //正确,可以引用一个非常量的iconst int &bb=10; //也正确,可以引用一个非常量的纯数字10const int &cc=aa*2;//也正确,可以引用一个表达式

甚至,常量和非常量的类型不一居然也可以(一个double居然可以赋值给一个const int的引用):

double b=3.25;const int &a=b;//正确,输出a的值是3const int a=b;//也正确

依据C++ primer中所讲,这是因为,编译器内部利用double b生成了一个临时的整形常量,然后把常量绑定到了a上。

这样输出a的值是3。

那么把一个常量a,定义为非常量b的引用,即const int &a=b,因为我们知道常量是不允许修改的,因此不能通过a来修改b的值,而b的值还是可以改的。此时:如果b也是int,改了b也会再影响a;如果b是double类型,那a还是第一次定义时的值(说白了二者其实没有什么关联,虽然表面看起来是引用)。

三、const的“指针”难点

1.如果定义的是指针,和上面类似,普通指针不能指向常量,常量指针却可以指向非常量。

常量指针必须被初始化,一旦被初始化,指针就不能改变了,即常量指针指向的那个地址不能变了。虽然地址不能变了,但不代表地址里面存放的数字不能变了,因此,常量指针指向的数据还是可以变的(当然指向的这个数据如果也是常量除外)

int b=10; int *const a=&b; //定义常量指针a,指向非常量b的地址,之后a指向的地址不能变了 *a=*a+1;//但是a指向的地址里的数字还是可以变的

2.顶层const和底层const:

顶层const表示指针本身是个常量,底层const表示指针所指向的对象是个常量。(更一般的说,顶层const代表任意的对象是常量,例如const int c=10 中 c也是一个顶层const,尽管它不是指针;而用于声明引用的const是底层const,例如 const int &c=10中,c是一个底层const,尽管它也不是一个指针)

这块对于初学者来说,十分繁琐,类型、const、指针、名字 各种排列组合,让人不知道定义的是什么,哪个可变哪个不可变。

我这里借用这位博主里面讲到的一个技巧:

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

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

即:*在前,指针是常量(顶层const);*在后,指向的是常量(底层const);*在正中间,全都是常量;*被括号括住的,指针是常量。

大家可以进这位博主的中,看看他提供的各种常见表示和答案,利用上述的口诀,做一个自测。(所谓“前“和”后“指的是*和const的相对位置,不包括类型)

如果指针不是常量,指向的是常量的话,说明指针是可以变的,但是指针解引用以后,就不能变了,即:

int b=10;int c=8;int const*a=&b; //*在后,指向的是常量,即*a是常量,(但不是说b非得是常量!!只不过是不能通过a来修改b的值)*a=*a+1; //错误,a指向的是常量,不可以修改a=&c; //由于a不是常量指针,因此可以改变成ccout<<"a="<<*a<

注意!!所谓“a指向常量”,意味着*a是个常量,不能改变。但并不意味着int const*a=&b 中b非得是一个常量!此处不能通过*a

来修改b,但是可以直接修改b,间接的影响*a的值。

这里和前面的引用很像:const int &a=b,b如果是个int,可以修改b,修改b会影响a。但是,对于引用来说,可以把一个const int 引用一个非常量的double(这种情况下double变了,const int不会跟着变);对于指针来说,却不可以把一个int const *指向一个非常量的double值。 

转载地址:https://blog.csdn.net/zkk9527/article/details/89502524 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:SLAM14讲学习笔记(十一)g2o图优化中的要点与难点(前端VO中雅克比矩阵的定义)
下一篇:Cmake入门(四)find_package

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年04月13日 14时53分04秒