c++ const的详细总结

1.const关键字

c语言关键字const是constant的缩写,意思是不变的。当程序员定义了一个const对象,则编译器就不允许程序员再对该对象进行修改,相当于该对象仅仅是一个只读对象。const语法变化多端,而且许多面试中也会涉及到const的相关知识点。所以在此做一个总结,加深一下const的印象,也方便自己以后回顾相关的知识点。

2.定义一个const对象

定义一个const对象非常简单,只要对普通的对象加上const的修饰成了一个const对象:

const int i = 10; 
const double j = 6.6; 

一旦被const修饰后,任何对该对象的修改都是不被编译器允许的

const int i = 10;
i = 20; // error 编译失败,i是只读的,不能修改i的值

注意:由于const对象是不能被修改的,所以在定义const对象时必须初始化。

const int i ; //error  未进行初始化,编译失败

3.const引用

在c++中引用的类型需要和所引用的对象类型严格一致,但是给引用加上const修饰符,使其成为一个const引用之后则可以突破这一限定,c++允许const引用绑定非常量对象,字面值甚至是表达式。
普通的引用:

int i = 10;
int &a = i; // 正确
double &b = i; //error i的类型和b的类型不一致

const int i = 10;
int &a = i;//error 普通引用不能引用常量

int &b = 10;// error 同理,不能绑定常量

为何普通引用不能绑定常量?因为避免通过引用修改常量的值,因此将普通引用绑定const对象是不合法的。
const引用:

const int i = 10;
const int &a = i;//ok  const引用绑定const对象

const int &b = 10;// ok const引用绑定常量

double i = 9.9;
const int &a = i;//  ok 相当于做了强制类型转换

小结:非const引用只能绑定与该引用类型相同的对象;const引用则可以绑定与引用类型不同但是相关联的对象上。

4.const指针

const指针是const知识中的一个重点,也是非常容易记混淆的地方。const修饰指针的用法主要有以下几种:
第一种:const修饰*(指针)

int i = 10;
int *const p = &i;

上述的定义语句则是定义了一个指向整型对象的常指针,即const修饰的是指针,指针的指向不可以改变,但是指针所指之物是可以被改变的,如下:

int i = 10;
int j = 20;
int *const p = &i;
*p = 20; // ok 指针所指之物的值是可以改变的
p = &j; // error 指针的指向只能是i,而不能被变更到j

第二种:const修饰被指物

const int i = 10;
const int *p = &i;
/********下面这种定义也可以*********/
int i = 10;
const int *p = &i;// i可以不是常量

上述的定义语句则是定义了一个指向常量的指针。const修饰的是int,即指针的指向可以改变,但是指针所指的内容不能被改变,也就是不能通过指针修改其值。

int i = 10;
int j = 20;
const int *p = &i;
*i = 20; //error 不能修改指针所指的内容
p = &j; // ok  可以修改指针的指向

第三种:const修饰被指之物和指针

int i = 10;
const int *const p = &i;

上述的定义语句则是定义了一个指向常整型对象的常指针。int和*都被const修饰,所以指针的指针指向不能被改变,被指之物也不能被改变。

int i = 10;
int j = 20;
const int *const p = &i;
*p = 20; //error 被指之物是const,不能被改变
p = &j; // error 常指针不能改变指向

小结:const与指针的结合主要有以上几种用法,究竟是修饰指针还是修饰类型,只需要记住:如果关键字const出现在星号左边,则被指物是常量;如果出现在星号右边,则表示指针自身是常量;如果出现在星号两边,则被指物和指针都是常量,都不允许被改变。

另外需要值得注意的是:
const对象的地址只能用const指针来保存

const int i = 10;
int *p = &i; // error 只能用const指针来保存
const int *p = &i; //ok

5.const和类成员

const也可以修饰类的成员函数。一般情况下,如果在一个类中的函数不会修改类的其他数据成员时,则最好用const加以修饰。常成员函数的说明格式如下:

<类型> <函数名> (<参数>) const 

一旦成员函数被声明为常成员函数,如果该函数修改了数据成员或者调用了其他非const函数,则会引起编译器报错。另外如果const修饰的是一个类,则该类的所有数据成员都无法被修改。

const修饰函数也是函数重载的一个方法,并且const对象默认调用const成员函数,如下:

#include <iostream>
using namespace std;
class A{
	public:
		A(int a,int b)
		{
			ma = a;
			mb = b;
		}
		void fun();
		void fun() const;
	private:
		int ma;
		int mb;
};

void A::fun()
{
	cout << ma << endl;
}
void A::fun() const
{
	cout << mb << endl;
}

int main()
{
	A a(1,2);
	const A b(3,4);
	a.fun();
	b.fun();
	
	return 0;
} 

结果如下:

1
4

这就说明普通对象a调用了普通成员函数,const对象b则调用了const成员函数。
const除了修饰类的成员函数,也可以修饰类的成员变量。但是被const修饰的成员变量只能在构造函数的初始化列表中进行初始化,而不能在类中进行初始化。

#include <iostream>
using namespace std;
class A{
	public:
		A():i(100) // ok 使用初始化列表初始化
		{
			
		}
		void fun()
		{
			cout << i << endl;
		}
	private:
		const int i = 100; // error 不能在类中初始化
};
int main()
{
	A a;
	a.fun();
	return 0;
} 

但是在类中初始化也不会报错,只是好像对它初始化没有意义,如下:

#include <iostream>
using namespace std;
class A{
	public:
		A():i()
		{
			
		}
		void fun()
		{
			cout << i << endl;
		}
	private:
		const int i = 100;
};
int main()
{
	A a;
	a.fun();
	return 0;
} 

输出结果:

0  

可以看出在类中进行的初始化并没有起到效果。

好了,夜色降临,睡觉!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值