[C++] 关于const

  • const对象

在C/C++中,有一个关键字叫const。它能够把一个对象转换为一个常量(或者说声明一个常量)。这里用int举例,适用于其他各种类型,包括类类型。

int a = 5;               //正确,a被初始化为5
int b;                   //正确,b未被初始化,其初始值为垃圾数据
const int ca = 6;        //正确,声明一个常量ca并初始化为6
const int cb;            //错误,声明一个常量cb但未初始化
  • const引用

int a = 6;            //定义一个变量a并初始化为6
int &ra = a;          //定义一个整型引用并将其绑定到变量a上
int b = 7;            //定义一个变量b并初始化为7
const int &crb = b;   //定义一个整型常量引用并将其绑定到b上
const int ca = 5;     //定义一个整型常量ca并初始化为5
const int &rca = ca;  //定义一个整型常量引用并将其绑定到ca上

ra = 8;               //正确,此时a的值被修改为8
crb = 6;              //错误,不能通过常量引用修改其绑定对象的值
rca = 8;              //错误,不能通过常量引用修改其绑定对象的值      

等等等等,下列写法也是可以的:
int a = 7;
const int &cra1 = a;
const int &cra2 = 5;
const int &cra3 = sizeof(int);
//输出分别为:7 5 4

常量引用可以绑定常量或变量,不能通过常量引用修改其绑定对象的值。若某常量引用绑定的是变量,则能够通过绑定了该变量的其他“非常量引用”修改该变量的值。

  • const与指针

int a = 5;                   //定义一个整型变量a并初始化为5
int *pa = &a;                //定义一个整型指针变量pa并初始化为&a
const int *cpa = &a;         //定义一个整型指针常量cpa并初始化为&a

const int b = 6;             //定义一个整型常量b并初始化为6
int *pb = &b;                //错误,&b为const int*类型,不能将其转化为int*类型

int d = 1;                   //定义一个整型变量d并初始化为1
const int cd = 9;            //定义一个整型常量cd并初始化为9
const int *cpd = &d;         //定义一个整型指针常量cpd并初始化为&d
const int *cpcd = &cd;       //定义一个整型指针常量cpcd并初始化为&cd

指针本身是一个常量不意味着一定不能通过指针更改它所指向的对象的值,能否通过指针更改其所指向的对象的值,取决于它指向的对象的类型。

int a = 6;
const int c = 5;
int b = 4;

const int *pa = &a;  //pa是整型指针,其指向能够改变,其指向的对象为常量(不可通过pa更改其指向对象的值)
*pa = 45;            //错误,pa所指向的对象是整型常量,不可更改
pa = &b;             //正确,将pa的指向更改为整型变量b
pa = &c;            //正确,将pa的指向更改为整型常量ca

int *const pb = &b;  //pb是整型指针,其指向不能改变,但是指向的对象是变量,可以通过pb改变其所指向对象的值
*pb = 7;             //正确,可以更改pb所指向对象的值
pb = &a;             //错误,不能更改pb的指向
pb = &c;            //错误,不能更改pb的指向
  • 顶层const与底层const

指针是一个对象,同时它又能指向一个对象。指针可以是变量或者常量,其指向的对象也可以是变量或者常量。关于笔试面试题中的各种const指针,我总结一共有四种情况:变量指向变量,变量指向常量,常量指向变量,常量指向常量。

有以下两个名词:顶层const和底层const。

顶层const表示指针本身是个常量,而底层const表示指针指向的对象是个常量。

下面是《C++ Primer 5th》中关于顶层const与底层const的例子:

int i = 0;
int *const p1 = &i;		//不能改变p1的值,顶层const
const int ci = 42;		//不能改变ci的值,顶层const
const int *p2 = &ci;		//允许改变p2的值,底层const
const int *const p3 = p2;       //int左侧的是底层const,右侧的为顶层cosnt
const int &r = ci;		//顶层const

i = ci;				//正确,将常量的值给赋值给变量
p2 = p3;			//正确,p2和p3指向的类型相同,p3顶层const的部分不影响

int *p = p3;			//错误,p3包含底层const的含义,而p没有
p2 = &i;			//正确,int*能够转化为const int*
int &r = ci;			//错误,整型变量不能绑定到整型常量上
const int &r2 = i;		//正确,整型常量可以绑定到整型变量上	

当我们更改一个const对象(或指针)时,需要考虑:

1、指针本身能否更改(指向能否更改)。

2、指针指向的对象的值能否更改(指向的对象为常量或变量)。

当执行对象的拷贝操作时,拷入和拷出的对象必须具有相同的底层const资格,或者两个对象的数据类型能够转换。一般来说,非常量可以转化为常量,反之则不行。(《C++ Primer 5th》P58)

  • 类的const成员函数

不修改数据成员的函数都应该声明为const类型。如果在const成员函数中修改了数据成员,或者调用了其他非const成员函数,都会产生错误。

class Example {
public:
        Example(int _value = 0) : value(_value) {     
        }

	int getValue() {
		cout << "not_const" << endl;
		return value;
	}

	int getValue () const {
		cout << "const" << endl;
		return value;
	}
private:
	int value;
};
/*这样的一组例子构成函数重载,当Example类的const对象调用getValue()时,会执行const函数,当Example类的非const对象调用getValue()时,会执行非const函数*/

int main() {
	Example eg1(5);
	const Example eg2(2);

	cout << eg1.getValue() << endl;
	cout << "------------" << endl;
	cout << eg2.getValue() << endl;

        return 0;
}
/*
输出为:
not_const
5
------------
const
2
*/

 

有关const的内容就先写到这里,如果以后遇到新的问题,会在这里继续补充~

20190214 10:04

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值