C++中的const关键字总结

一、概念

const 修饰符的作用就是修饰常量,即被其修饰的东西只能读取,不能被修改。

1.1 作用域

在C和C++中全局const变量的作用域相同,都是当前文件,不同的是它们的可见范围。
C语言中const全局变量的可见范围是整个程序,在其他文件中使用extern声明就可以使用。
而C++中const全局变量的可见范围仅限于当前文件,在其他文件中不可见,所以它可以定义在头文件中,多次引用都不会出错。
不过如果你是用的是GCC,你可以通过extern关键字来扩大C++全局const变量的可见范围。

extern const int n=10;

如此n的可见范围就扩展到了整个程序,可以使用extern声明来读取。但在VS/VC中,并不支持该操作。

1.2 与#define的区别

const与#define 存在着一定的差别。
(1)首先#define仅仅只是简单的替换,并不会进行类型检查。
(2)const修饰符可以保护被修饰的东西,防止意外修改,提高程序的健壮性。
(3)编译器会将const常量保存在符号表内,因此效率很高。

二、应用

2.1 const定义常量

const定义常量的格式通常如下:

const type name=value;

其中const和type是用来修饰变量的,它们的位置可以互换,即可写为

type const name=value;

另外建议将name的首字母大写,提示程序员,该变量为一个常量。
由于常量一旦被创建,其值就不能再改变,所以变量必须在定义的同时赋值。

2.2 const用于指针

const可以与指针一起使用,既可以限制指针本身,也可以限制指针指向的变量。
根据const与指针之间不同的排序会有不同的含义。

const int *p1;//限制*p1的数据,限制int
int const *p2;//限制*p2的数据,限制int
int * const p3;//限制p3指向的数据,限制int*
const int * const p4;//即限制*p4,也限制p4
int const * const p5;//即限制*p5,也限制p5

2.3 const用于函数形参

const可以用于函数形参当中,如果形参是一个指针,为防止在函数内部修改指针所指向的数据,便使用const来限制。
实际使用案例如下:

int puts(const char* str,const int*str)

2.4 const用于成员变量

const用户常量和普通const常量类似,只需要在声明时加上const关键字即可。

class A
{
	const int a;
	A(int x):a(x){}
};

初始化const成员变量只有一个方法,就是通过构造函数的初始化列表初始化。

2.5 const用于成员函数

const成员函数可以使用类中的所有成员变量,但是不能修改它们的值,其主要是为了保护数据而设置的。
通常会将get函数设置为常成员函数。
常成员函数需要在声明和定义的时候在函数头部的结尾加上const关键字。

class A{
	int a;
	int get_a()const;
};
int A::get_a() const{
	return a;
}

在成员函数中,根据const的位置不同会有不同的含义:

class A{
const int * f1(){}//表示返回值为const int *类型,不能被修改
int const * f2(){}//等同于const int * f1()
int * const f3(){}//返回值为int*,且不是常成员函数,两种可能:f3指向的函数体不可变,或者加在这个位置基本无效。
int * f4 () const {}//表示常成员函数,只能读取成员变量的值,不能修改。
};

2.6 const用于对象

在C++中,被const修饰的对象,被称为常对象。一旦将对象定义为常对象之后,就只能调用类中的const成员(成员常量和常成员函数)。注意:上一句中的调用为,不能使用非常成员函数,能够读取成员常量和成员变量,但不能修改其值。
定义常对象的语法为:

const class object(params);
class const object(params);

定义常类型指针的语法为:

const class *p=new class(params);
class const *p=new class(params);

常类型指针会将指向的类型对象定义为常对象。

2.7 const 用于引用

在C++中,被const修饰的引用,被称为常引用。

const int &A;

需要注意的是编辑器会为临时数据创建一个新的、无名的临时变量中,然后再将引用绑定到临时变量。这里的临时变量是会分配内存的。
为什么常引用会创建临时变量,而普通引用不会创建临时变量的?
因为普通引用拥有读取和修改的权限,需要保持引用所绑定的数据与原本的数据进行同步更新,因此如果创建两份不同的数据,就失去了引用的意义。而常引用只需读取数据的值,不需要考虑同步更新的问题,创建const引用创建临时变量反而会使得引用更加灵活和通用。

为什么会说const引用更加灵活?
为引用加上const修饰之后,不但可以将引用绑定临时数据,还是可以将引用绑定到类型相近的数据上。
将引用绑定到类型相近的数据上如下所示:

double i=1.2;
const int &ci=i;

注意:这里可以使用基类引用绑定到派生类对象,普通引用也可以。
此外引用类型的函数形参尽量加上const。

三、const的类型转换

首先我们的清楚一个概念,那就是const int* 和int *是两个不同的类型

由于int拥有读写的权限,而const int 只有读的权限,所以int可以直接转换为const int,而const int* 不可以直接转换为int*。因为通常我们都会为保证代码的健壮性,往往只会自动支持拥有更多权限的类型转为更少权限的类型,如此能够保证代码更加安全。

如果我们想要强硬的将const 类型的变量修改为非const类型的话,可以使用const_cast关键字。
它的功能就是去掉表达式中的const修饰或volatile修饰,即将const/volatile类型转为非const/volatile类型。

# include<iostream>
using namespace std;
int main()
{
	const int n=100;
	int *p=const_cast<int*>(&n);
	*p=234;
	cout<<"n="<<n<<endl;
	cout<<"*p="<<*p<<endl;
	return 0;
}

输出结果:
n=100
*p=234

输出结果之所以为上面的结果。是因为C++对常量的处理是一个值替换的过程,会将所有使用n的地方在编译期间被替换为100。
即:cout<<“n=”<<n<<endl; 转为 cout<<“n=”<<100<<endl;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值