详解C/C++中const限定符总结

 更新时间:2020年02月19日 09:33:54   作者:smile_zyk  
const是一种限定符,被const所限定的变量其值不可以被改变。。这篇文章主要介绍了C/C++中const限定符总结,通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

const限定符

const是一种限定符,被const所限定的变量其值不可以被改变。

const的初始化

由于const一旦创建其值就不能够被改变,所以我们必须对其进行初始化

const int a;//错误,const变量必须进行初始化!
const int b=10;//正确,编译时初始化
const int c=get_size();//正确,运行时初始化

相同类型的变量相互初始化时,不论变量是否被const限定我们都可以进行随意的相互拷贝。因为在拷贝过程中我们只会用到等式右边变量的右值属性,无须在意其是否可以改变。

int m = 5;
const int n = m;
int j = n;

const与指针

顶层const与底层const

对于指针来说,由于其指向另一片内存的特点,有三种不同的const情况,即:

  1. 指向常量的指针(const int *)
  2. 常量指针(int * const)
  3. 指向常量的常量指针(const int *const)

我们一般称符合第一种情况的为具有底层const属性。

符合第二种情况的为具有顶层const属性。

第三种情况兼而有之。

关于带有const的指针的相互赋值(或者初始化)问题

  • 顶层const并不会影响变量间的相互拷贝(原因是顶层const只保证自身的值不会改变,const没有改变自身的变量类型,在拷贝时只是使用该类型的右值)。
  • 如果等号右边是底层const,那么等号左边必须保证为相同的底层const(或者等号右边的类型可以转换成等号左边的类型),否者表达式无法通过编译。

关于底层与顶层const的一些想法

const的底层与顶层属性似乎只在指针上存在。但是c++primer中有这样的代码和注释:

const int ci=1,&cr=ci;
auto b=ci;//b是一个整数(ci的顶层const特性被忽略掉了)
auto c=cr;//c是一个整数(cr是ci的别名,ci本身是一个顶层const)

这段代码是为了说明auto说明符一般会忽略掉顶层const的特性,在注释中明确写着 ci本身是一个顶层const 。

这也与我的看法一致,底层与顶层const实际上并不是指针所特有的,只要是不能改变对象自身的对象都具有顶层const,而不能改变自己所指向的对象的对象都具有底层const。

从这个角度看,引用实际上自带顶层const。

底层const的隐式转换

上面提到,只有在等号右边和等号左边的类型具有相同的底层const属性,才可以进行赋值或者初始化。

然而有些时候等号右边可能并不具有和等号左边一致的底层const却依然可以成立,这是因为等号右边的类型发生了隐式转换从而具有了和等号左边类型相同底层const属性。

例如:

int i=5;
int *p=&i;
const int *cp=p//int*隐式转换称为了const int*

为什么int 转换成const int 被设定为合法的呢,因为在将int 转换为const int 的过程中用户的权限变小了,在这一转换过程中并不会使程序变得不可靠。

由此我们可以得知非底层const的指针是可以通过隐式转换转变成底层const的。

const与引用

可以把引用绑定在const的变量上,称为const的引用,对常量的引用。

与普通的引用不同的是,对常量的引用不能被用作修改它所绑定的对象

const int ci=5;
const int &r=ci;
r=6//错误不可以通过常引用来修改值
int &r2=ci//错误,试图让一个非常量引用指向一个常量对象。

const引用的初始化

我们知道对于引用来说初始化时一定要用一个对象初始化,且该对象的类型需要与之匹配。

但是const的引用是个例外,在初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果能转换成引用的类型即可,甚至允许为一个常量引用绑定非常量的对象、字面值或者是表达式。

int i=42;
const int &r1=i;//允许将const int&绑定到一个普通int对象上
const int &r2=3.14;//正确:r2是一个常量引用
const int &r3=r1*2;//正确:r3是一个常量引用
int &r4 =r1*2;//错误,非常量引用不能用表达式初始化

C++primer中给出了可以这么做的原因:

要想理解这种例外情况的原因,最简单的方法是弄清楚当一个常量引用被绑定到另外一种类型上都时到底发生了什么:

double dval=3.14;
const int &ri=dval;

此处ri引用了一个int型的数。对ri的操作应该是整数运算,但dval却是一个双精度浮点数而非整数。因此为了确保让ri绑定一个整数,编译器把上述代码变成了如下形式:

const int temp=dval;//由双精度浮点数生成一个临时的整型常量
const int &ri=temp;//让ri绑定这个临时量

在这种情况下,ri绑定了一个临时量对象。所谓临时量对象就是当编译器需要一个空间来暂存表达式的求值结果时临时创建的一个未命名的对象。C++程序员们常常把临时量对象简称为临时量。

const与auto类型说明符

auto类型说明符是C++11中新引入的类型说明符,可以自动推断类型。

编译器推断出来的auto类型有时候和初始值的类型并不完全一样,编译器会适当的改变结果类型使其更符合初始化规则。

auto在推断带有const的对象时,编译器一般会忽略掉顶层const,同时底层const则会保留下来。 另外对于引用由于引用没有真正的实体,所以如果用一个引用来初始化auto类型时,auto实际上为引用所指向的对象的类型,而非引用,如果要说明其为引用类型,需要使用auto&。

const int ci=i,&cr=ci;
auto b=ci;//b是一个整数(ci的顶层const特性被忽略掉了)
auto c=cr;//c是一个整数(cr是ci的别名,ci本身是一个顶层const)
auto d=&i;//d是一个整型指针(整数的地址就是指向整数的指针)
auto e=&ci;//e是一个指向整数常量的指针(对常量对象取地址是一种底层const)

如果希望推断出的auto类型是一个顶层const,需要明确指出:

const auto f=ci;//ci的推演类型为int,f是const int。

总结

以上所述是小编给大家介绍的C/C++中const限定符总结,希望对大家有所帮助,也非常感谢大家对脚本之家网站的支持!

相关文章

  • Opencv实现轮廓提取功能

    Opencv实现轮廓提取功能

    这篇文章主要为大家详细介绍了Opencv实现轮廓提取功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-05-05
  • C语言中数据在内存如何存储

    C语言中数据在内存如何存储

    本文详细讲解了C语言中数据在内存如何存储,文中通过示例代码介绍的非常详细。对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-12-12
  • C++利用代理模式实现远程代理,虚拟代理和保护代理

    C++利用代理模式实现远程代理,虚拟代理和保护代理

    今天给大家简单介绍代理模式,一个很简单的设计模式,旨在不改变原对象的情况下通过代理对象来控制对原对象的访问。代理模式根据具体情况还可以分为远程代理、虚拟代理、保护代理等,下面来介绍一下
    2023-04-04
  • C++中set/multiset容器详解(附测试用例与结果图)

    C++中set/multiset容器详解(附测试用例与结果图)

    set/multiset属于关联式容器,底层结构是用二叉树实现,下面这篇文章主要给大家介绍了关于C++中set/multiset容器的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-02-02
  • C语言详解实现猜数字游戏步骤

    C语言详解实现猜数字游戏步骤

    猜数字是兴起于英国的益智类小游戏,起源于20世纪中期,一般由两个人或多人玩,也可以由一个人和电脑玩。游戏规则为一方出数字,一方猜,今天我们来实现这个游戏案例
    2022-07-07
  • VC判断一个文件为目录的方法

    VC判断一个文件为目录的方法

    这篇文章主要介绍了VC判断一个文件为目录的方法,在Windows应用程序设计中非常具有实用价值,需要的朋友可以参考下
    2014-10-10
  • QT实现贪吃蛇游戏代码详解

    QT实现贪吃蛇游戏代码详解

    本文主要为大家详细介绍了在QT中实现贪吃蛇游戏的详细教程,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • C语言实现影院管理系统

    C语言实现影院管理系统

    这篇文章主要为大家详细介绍了C语言实现影院管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12
  • 节序问题:解析大小的端判定

    节序问题:解析大小的端判定

    本篇文章是对大小的端判定进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++中Digraphs、Trigraphs和Tokens的深入讲解

    C++中Digraphs、Trigraphs和Tokens的深入讲解

    这篇文章主要给大家介绍了关于C++中Digraphs、Trigraphs和Tokens的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C++具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-09-09

最新评论