c++系列文章(4):const限定符

博客链接

初始化

  const对象一旦创建后其值就不能再改变,所以const对象必须初始化,且初始值可以是任意复杂的表达式。

const int i = getsize(); //运行时初始化
const int j = 1; //编译时初始化

  当以编译时初始化的方式定义一个const对象时,编译器将在编译过程中把用到该变量的地方替换成对应的值。为了执行替换,编译器必须知道常量的初始值,因此默认情况下,const对象被设定在仅在文件内有效,当在多个文件中出现了同名的const变量时,其实等同于在不同的文件中分别定义了独立的变量。
  某些时候,我们不希望编译器为每个文件分别生成独立的变量,而是希望像普通变量一样在不同文件之间共享const变量,也就是说只在一个文件中定义const,而在其他多个文件中声明并使用它。解决的方式是,对于const变量不管是声明还是定义都添加extern关键字,这样只需定义一次即可。

//file_1.cc
extern const int bufSize = fcn();
//file_1.h
extern const int bufSize; //与file_1.cc中定义的bufSize是同一个

const和引用

  说明:程序员常把对const的引用简称为“常量引用”。
  之前提到过,引用的类型必须与其所引用对象的类型一致,但有两个例外。第一种例外就是在初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果能够转换成引用的类型即可。尤其,允许为一个常量引用绑定非常量的对象、字面值、甚至一个一般表达式

int i = 1;
const int &r1 = i; //正确,允许将常量引用绑定到一个普通变量上
const int &r2 = 1; //正确,允许将常量引用绑定到一个字面值上
const int &r3 = i*2; //正确,允许将常量引用绑定到一般表达式上
int &r4 = i*2; //错误,r4是普通的非常量引用,不能绑定到一个表达式上
double d = 3.14;
const int &r5 = d; //正确,double变量能够转换成int类型

  为什么能够将一个普通double类型变量绑定到一个int类型的const引用上?实际上,当一个常量引用被绑定到另外一种类型上时,这个常量引用实际是绑定在了一个临时变量上。

const int temp = d; //由double数生成一个临时的int变量
const int &r5 = &temp; //r5实际是绑定在这个临时变量上

  常量引用只是对引用可参与的操作做出了限定,对与引用的对象本身发是不是一个常量并未限制。因此常量引用既可以绑定const对象也可以绑定非常量对象,如果绑定的是非常量对象,则只是不能通过引用改变该对象,但可以直接通过该对象进行改变。

int i = 1;
const int &r = i; //正确,常量引用可以绑定到非const对象上
r = 2; //错误,不能通过常量引用改变绑定对象的值
i = 2; //正确,i是非const对象,可以改变其值

const和指针

  指向常量的指针

  和常量引用类似,指向常量的指针不能用于改变其所指对象的值,要想存放常量对象的地址,只能使用指向常量的指针。

const int i = 1;
int *p1 = &i; //错误,p1是一个普通指针,不能存放常量对象的地址
const int *p2 = &i; //正确,只能用指向常量的指针存放常量对象的地址
*p2 = 2; //错误,指向常量的指针不能用于改变其所指对象的值

  之前提到过,指针的类型必须与其所指向对象的类型一致,但有两个例外。第一种例外就是允许一个指向常量的指针指向一个非常量对象

int i = 1;
const int *r = &i; //正确

  和常量引用类似,指向常量的指针只是规定不能通过指针改变对象的值,而没有规定那个对象的值不能通过其他途径改变。

  常量指针

  指针是对象而引用不是,因此指针也能像其他类型一样,将指针本身定义为常量。常量指针必须初始化,而且一旦初始化,则它的值(也就是存放在指针中的那个地址)就不能改变了。把*放在const之前用以说明指针是一个常量。

int i = 0;
int *const  p1 = &i; //p1将一直指向i
const int j = 0;
const int *const p2 = &j; //p2是一个指向常量的常量指针

  为了区分指针的const的属性,用顶层const表示指针本身是一个常量,用底层const表示指针所指的对象是一个常量。
  当执行对象的拷贝时,常量是顶层const还是底层const区别明显。对于顶层const而言,由于拷贝操作不会改变被拷贝对象的值,因此拷入或者拷出的对象是否是常量都没有影响。如果是底层const,则拷入和拷出的对象必须具有相同的底层const属性,或者两个对象的数据类型必须能够转换,一般来说非常量能够转成常量,反之则不行

const int i = 0;
const int *p1 = &i;
int *p2 = p1; //错误,p1包含底层const属性,而p2则不包含
int j = 0;
int *p3 = &j;
cosnt int *p4 = p3; //正确,非常量能够转换成常量
利用 TensorFlow 训练自己的目标识别器。本文内容来自于我的毕业设计,基于 TensorFlow 1.15.0,其他 TensorFlow 版本运行可能存在问题。.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值