详解const在位置上的差异-(包含类与对象)

1.const与普通变量

定义const变量:初始化完成后,值不可被修改

`在这里插入图片描述

2.const与指针

相信很多人都记不清const在指针前后到底修饰什么,下面请看

int a = 5;
const int *p =&a;
*p = 20;   //error  不可以通过修改所指向的变量的值

int b =20;
p = &b; //right  指针可以指向别的变量

对于const在最前面我们可以想象没有int* p,那么const是不是修饰&a,那么&a是不是就没法修改,也就是a无法修改了,但是p不受影响,p是什么,p是指针,所以p的指向还是可以改变的。
当为常量指针时,不可以通过修改所指向的变量的值,但是指针可以指向别的变量。

int a = 5;
int *const p = &a;
*p = 20;     //right 可以修改所指向变量的值

int b = 10;
p = &b;      //error 不可以指向别的变量

const这次在里面是不是紧靠着p,p是指针,是不是p的指向无法改变,&a是不是不受影响了,那么a就可以正常改变,你理解了么?
当为指针常量时,指针常量的值不可以修改,就是不能指向别的变量,但是可以通过指针修改它所指向的变量的值。

总结:
1.如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;
2.如果const位于星号
的右侧,const就是修饰指针本身,即指针本身是常量。

3.const与函数

const int fun(const int a)const;

const修饰返回值

修饰返回值 const int fun();不能修改返回值。

const修饰形参

int fun(const int x);x在函数体内无法被修改

在这里插入图片描述

const修饰this指针(类与对象)

请看下面的代码

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<assert.h>
using namespace std;

class Date
{
public:
	Date(int year, int month,int day ,int &i)
		:_year(year)
		,_month(month)
	    ,_x(1)
		,_ref(i)
	{
		
		_day = day;
	}


	//总结一下:只读函数可以加const,内部不涉及修改成员的都是只读函数
	void Print()const 
	{
		cout << _year << '/' << _month << '/' << _day;
	}

	void Print()
	{
		cout << _year << '/' << _month << '/' << _day;
	}

	int& func()//int& func()返回局部变量的引用也会有问题
	{
		int ret;
		return ret;//返回的不是ret,而是ret的拷贝,临时对象具有常性,不能修改
	}


	//日常自动生成就可以
	//不想被取到有效地址
	Date* operator&()
	{
		return this;
	}

	const Date* operator&()const
	{
		return this;
	}

	friend ostream& operator<<(ostream& out, const Date& d);//Date* this在out前面
	 friend istream& operator>>(istream& in,  Date& d);//不能加const
	

private:
	int _year; //每个对象的声明
	int _month;
	int _day;

	//必须定义时初始化
	const int _x;
	int& _ref;
};

ostream& operator<<(ostream & out, const Date& d)//Date* this在out前面
{
	out << d._year << '/' << d._month << '/' << d._day << endl;
	return out;
}

istream& operator>>(istream& in,  Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}

void test_date1()
{
	//const Date d1(2023, 7, 27);//传着传着就有可能变成const对象,const对象不能调用
	                          //非const函数,权限不能放大
	//d1.Print(); 
	//d1.func() = 1;   error

}

//int main()
//{
//	test_date1();
//}

struct SeqList
{
public:
	void push_back(int x)
	{
		_a[_size++] = x;
	}

	size_t size()const
	{
		return _size;
	}

	size_t capacity()const
	{
		return _capacity;
	}

	int& operator[](size_t i)//写/读
	{
		assert(i < _size);
		return _a[i];
	}

	const int& operator[](size_t i)const//只读函数
	{
		assert(i < _size);
		return _a[i];
	}

private:
	int* _a = (int*)malloc(sizeof(int) * 10);
	size_t _size = 0;
	size_t _capacity = 0;
};

void Print(const SeqList& s)//const修饰的本质是s的成员不被修改,不是s._a里面的数据不被修改
{                           
	for (size_t i = 0; i < s.size(); i++)
	{
		cout << s[i] << " ";
		//s[i]++;

	}
}

int main()
{
	SeqList s;
	s.push_back(1);
	s.push_back(2);
	s.push_back(3);


	Print(s);
	
	cout << endl;
	return 0;
}

什么时候const修饰this呢,我们可以认为只读函数可以加const,内部不涉及修改的都是只读函数

在这里插入图片描述
但是为什么print函数我们要写两次呢,因为Date在其他函数调用过程或者初始化的时候成为const常量
在这里插入图片描述
而const对象不能调用非const函数,权限不能放大,所以就有了const版的print函数,所以我们认为只读函数最好都加上const。同理如下:
在这里插入图片描述
而对于第二个前面的const是因为
在这里插入图片描述
Print里面是const类型的形参,我们不希望s._a被改变,所以在函数前面也加了const,而operator【】函数有两个是因为一个是只读函数,而另有一个要可以修改,一个函数无法同时支持const和非const,所以写了函数重载。

调用问题:

请各位思考下面几个问题
在这里插入图片描述
1,3错,2,4对,因为加了const就相当于权限缩小了,所以权限小的不能调用权限大的,也就是const对象不可以调用非const成员函数,权限可以缩小,平移,但是不能放大

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值