C++类和对象(2)——取地址运算符重载

一、const成员函数

const放在成员函数参数列表后面进行修饰,那么这个成员函数就是const成员函数;const实际修饰的是成员函数形参中包含的this指针的形参,表明在这个成员函数内部不能对成员进行修改。

例如日期类里面的Print成员函数,它的形参是Date* const this,用来接收实参&d,那么在这个Print函数参数列表后面加上const,Print函数隐含参数就成了 const Date* const this,那么就不能通过这个this指针来改变指向的对象的数据成员了。

const不能修饰默认成员函数,默认成员函数编译器可以自动生成,函数内部对对象的修改是根据类的不而来变化的,也就是说默认成员函数中对象的可修改性不能由const来决定。

###代码示例:

//const修饰成员函数
class Date
{
public:
	Date() 
	{
		_year = 1;
		_month = 1;
		_day = 1;
	}
	void Print( )const //实际参数是const Date* const this
	{
		cout << _year << " " << _month << " " << _day << endl;
	}
	bool operator==(const Date& d) const//实际参数是const Date* const this,const Date& d
	{
		return _year == d._year &&
			_month == d._month &&
			_day == d._day;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;
	Date d2;
	d1.operator==(d2);//实参是&d1(参数类型是Date*)、d2;
	d1.Print();//实参是&d1,参数类型是Date*
	d2.Print();//实参是&d1,参数类型是Date*

	const Date d3;
	const Date d4;
	d3.operator==(d4);//实参是&d3(参数类型是 const Date*)、d4
	d3.Print();//实参是&d3,参数类型是(const Date*)
	d4.Print();实参是&d4,参数类型是(const Date*)
	return 0;
}
  • d1、d2都是Date类型,重载运算符 (==)  函数传参是Date* 和Date,const成员函数(operator==) 的形参是 const Date* const this,const Date& d,实参相较形参是访问权限的缩小,不会有问题;同理成员函数 Print() 也是;
  • d3、d4都是const Date类型,看到它们的Print() 函数,那么实参就是&d3或者&d4,对应的类型是const Date*,const成员函数恰好接收的就是const修饰指针指向的是对象内容的实参,那么这里就是访问权限的对等,自然不会有问题;

所以,给const成员函数传参时,传的可以是类的指针类型的实参,也可以是const修饰类的指针类型的实参;当然,const成员函数const是为了保证this指向的对象不被修改的,那么这个const修饰的成员函数定义时,自然不能出现要修改this指向的对象的行为。

###为理解透彻,再来看非const成员函数传参时访问权限放大的错误代码:

  • d1类型是const Date,那么这个对象的成员是不能被修改的;此时调用Print()函数,传参实参是const Date*,但是形参是Date* const this,这个形参的意思是:this指针本身不能被修改,但是this指向的对象是可以被修改的,那么显然这时权限放大了,是错的;要解决,要么去掉const Date d1前的const,将d1类型改为Date;要么给Print()函数参数列表后面加上const,使其成为const成员函数。

二、取地址运算符重载

取地址运算符重载分为普通取地址运算符重载和const取地址运算符重载,一般来说,取地址运算符重载是不需要我们实现的,编译器自己生成的就可以满足我们的需求;

###代码示例:

class Date
{
public:
		Date(int year=9,int month=1,int day=1)
		{
			_year = year;
			_month = month;
			_day = day;
		}
		//普通的取地址运算符重载
		Date* operator&()
		{
			return this;
		}
		//const取地址运算符重载
        //返回类型是const Date*,是因为const修饰了
		const Date* operator&()const
		{
			return this;
		}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1;
	cout << &d1 << endl;
	const Date d2;
	cout << &d2 << endl;
}

 

仅靠编译器生成的默认取地址运算符重载也能取到类的地址:

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值