Cpp关键字破解(一)【const】篇

本文深入探讨了const关键字在C++中的使用,包括const变量的初始化、核心思想、const引用、指向const对象的指针以及const指针。const引用允许用任意表达式初始化,而const指针则分为顶层const和底层const。此外,还介绍了如何在多文件中共享const对象以及顶层const的概念。
摘要由CSDN通过智能技术生成

const关键字总结

是什么

const(即单词constant)创建的变量的值不能改变,因为值不能修改,可以理解为常量,但是不存在真正的常量,只是在const的作用域中,该变量才不能被修改,超过了这个const的作用域,有可能是可以修改。

注意:const仅表示不能改变,不表示具体的变量类型,按照从右向左的方式来理解变量的命名,首先要说明这是一个什么类型的变量,其次才是变不变,因此const的位置应该在变量类型名左边。如下所示:

//从右向左读变量,首先a是一个int型变量,在这基础上,a才是一个值不能改变的int型变量
const int a = 0;		

初始化

因为const的对象创建以后就不能修改,因此在创建时必须初始化


怎么用

核心思想

const创建的对象只能完成不改变其本身值的操作,也就是说,**不管操作多复杂,只要不改变const对象的值,const对象都支持。**这个核心思想包含了两方面,1)阻止显式更新const对象;2)阻止隐式更新const对象,代码如下。

const int a = 0;
1)阻止显式更新a
{	//不合法
    a = 42;
}
2)阻止隐式更新a
{	//不合法
    int &a1 = a;
}
  • 阻止显式更新:很明显,不能直接改变const对象的值,这也是最直观的一种
  • 阻止隐式更新:定义一个非const类型的引用指向const对象。虽然并没有直接改变const对象a,但如果这一步合法了,那么通过非const类型的引用a1岂不是可以间接改变const对象a了么

const引用

有一种特殊情况:const对象(包括引用)在初始化时允许用任意表达式作为初始值,也就是说,可以将一个变量作为初始值赋给一个const对象。也就是说下面的情况是合法的:

int a0 = 0;
//(1)合法
const int a = a0;
//(2)合法
const int &aa = a0;

为什么这样是合法的呢,按照核心思想中的理解,就算现在把int变量a0作为初始值赋给const对象a,在初始化阶段给const赋值是合法的;但是将一个const引用aa指向一个int类型变量a0,不属于隐式更新的可能么,直接修改int变量a0不就是等于修改了它的引用aa么?

实际上像上面代码中第(2)种情况,将一个常量引用绑定到其他类型上时发生了一个转折,代码如下:

double a_double = 1.111;
const int &aa = a_double;

//上面两行代码等效于
double a_double = 1.111;
const int temp = a_double;	//临时常量进行强制类型转换
const int &aa = temp;

对于常量的引用之所以能够用任意表达式进行初始化,原因就是创建了一个临时的const常量进行了强制类型转换。

总结一下:对于常量的引用(const 类型 &引用名)所绑定的对象,是不是const对象都不要紧。关于const引用绑定一个非const对象的操作,经常发生在传引用进入一个函数内部,但不希望在函数内部改变该引用所绑定的对象的值的情况中。

指向const对象的指针&const指针

const与指针结合就不像const引用这么粗暴了,因为引用是别名,引用名与引用绑定的对象都是同一个,但是指针作为一种对象,与const对象结合一下就有了变化:

  • 指向const对象的指针:当一个指向const对象的指针被初始化以后,表示不能通过该指针修改所指对象的值。
  • 指针本身就是一个const对象,是真正的const指针const指针必须初始化,指针的值不能改变,就是const指针内存储的内存地址不能改变。可以通过const指针修改指向对象的值,除非指向的是一个常量对象那就不能修改。
//指向const对象的指针,也叫底层const
const int a = 0;
const int *a_p = &a;

//const指针,指针本身就是一个const对象,称为顶层const
int b = 0;
int *const b_p = &a;

同样是从右向左读,a_p的理解顺序为{指针,int类变量,常量}:a_p是一个指针,指向一个int类型的常量;b_p的理解顺序为{常量,指针,int类型}:b_p是一个const指针,指向一个int类型的变量。

const引用一样,指向const对象的指针一样要阻止显式更新(直接改变指针所指向对象的值)与隐式更新(使用普通指针指向常量对象):

const int a = 0;
const int *a_p = &a;

//1)阻止显式更新
*a = 1;	//不合法

//2)阻止隐式更新
int *a_ppp = &a;

但是,指向const对象的指针同样具有一种例外,对于常量指针的初始化,可以用任意表达式来赋值,是不是常量对象都没关系

const指针只是要求指针内存储的内存地址不能被修改,没有禁止这块内存上存储的变量的值不能修改:

int b = 0;
int *const b_p = &b;
*b_p = 1;		//合法,因为b_p内始终存储b的地址
int c = 2;
*b_p = &c;		//不合法,试图改变b_p指向的内存地址

多文件

若当前编写的文件中包含多个其他文件,并且在不同文件中都用到了const创建对象,甚至有可能const对象的名字都一样,这种情况会经常发生那。在默认情况下,一个文件中的const对象的作用域被设置为仅在当前文件内。

如果确实是想要在多个文件中共享一个const对象,也就是说只在一个文件中定义const对象并初始化,在其他文件中声明并使用该对象,办法就是将该const对象的定义和声明都添加extern关键字

//初次在一个文件中定义并初始化一个const对象
extern const int a = 0;

//在其他文件中声明该const对象后就能使用
extern const int a;

对于extern关键字的理解同样要遵循从右到左的顺序:变量a首先是一个int型变量,其次是值不能修改的int对象,最后才是可以在多个文件中共享的、值不能修改的int对象。


顶层const

概念

顶层const与底层const是针对指针来说的,因为指针也可以作为对象,所以指针是不是常量指针指向的对象是不是常量就是两个独立的问题。

顶层const:指针本身就是常量,为const指针

底层const:指针指向的对象是一个常量对象,即指向const对象的指针

除了指针和引用这种复合数据类型,其他所有普通类型(int、double等)的const对象基本都是顶层const。

一个指针既可以是顶层const又可以是底层const,此时表示一个const指针指向了一个const对象。

int a = 0;
const int *a_p = &a;	//底层const

int b = 0
int *const b_p = &b;	//顶层const

int c = 0;
const int *const c_p = &c;		//既是底层const又是顶层const
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值