const成员函数、cout/cin和重载运算符<<、>>、&

目录

一、为什么cout,cin可以自动识别类型?

二、留提取运算符重载(<<)

三、留插入运算符重载(>>)

四、对上述的总结:

五、const成员

成员函数原则:

六、默认成员函数-取地址操作符重载


一、为什么cout,cin可以自动识别类型?

我们知道cout是ostream类的对象,cin是istream类的对象,并且流插入运算符“<<”只能用于内置类型,不能用于自定义类型。

为什么可以用于自定义类型呐?

如下:

是因为C++进行了运算符重载,然后又通过函数重载,所以可以自动识别不同内置类型。

二、留提取运算符重载(<<)

想要自定义类型也可以用留提取运算符,此时需要自己定义留提取运算符重载。

void operator<<(iostream& out)
{
	out << _year << "年" << _month << "月" << _day << "日";
}

但此时我们会发现,如下情况:

会发现p1在运算符左边,cout对象在右边。

原因在于:双操作数的运算符规定,第一个参数是左操作数,第二个参数是右操作数。而运算符重载函数的第一个形参被this指针隐式占用了,ostream类对象的引用在第二个形参位置,所以在调用运算符重载使,只能是this指针指向的对象在运算符的左边,cout对象在运算符的右边,但这又不符合留提取的含义。

为了解决这一问题,有如下方法:

将运算符重载创建为全局函数:

这样就不存在this指针占用的问题,可以将形参位置条调换,就可以像正常情况那样调用运算符重载。

接着又产生一个问题,运算符重载不在是类的成员函数,而大多数情况成员变量都会定义为私有或保护,这就导致,运算符重载不能使用成员变量,此时有如下解决方法:

(1)、创建getX,setX等等成员函数,间接使用成员变量;

(2)、将运算符重载设置为类的友元函数。

上述问题明白后,这里又有一个新的问题:

日常的运算符是支持链式调用的,所以我们还需要完成这个操作。

很显然,这是返回值的问题,我们返回cout对象的引用out就可以了;

ostream& operator<<(ostream& out,Date& d)
{
	out << d._year << "年" << d._month << "月" << d._day << "日";
	return out;
}

三、留插入运算符重载(>>)

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

注意事项与cout类似。

四、对上述的总结:

(1)、其他运算符一般实现为成员函数,而=运算符必须实现为成员函数,<<、>>运算符必须实现为全局函数,这样才能让流对象作为第一个参数,才符合可读性;

(2)、流本质是为了解决自定义类型的输入和输出,这弥补了C语言的printf和scanf不能操作自定义类型的不足;

五、const成员

const 修饰的 成员函数 称之为 const 成员函数 const 修饰类成员函数,实际修饰该成员函数 隐含的 this 指针 ,表明在该成员函数中 不能对类的任何成员进行修改。(const Date* this)。
看如下情况:
我们发现当对象p1被修饰成const后就不能正常调用成员函数。
原因在于p1被const修饰后,&p1为(const Date*)类型,而普通成员函数的this指针是(Date*)类型,这属于将权限放大问题,this指针就不能正常接收实参。
此时我们规定如下:
在成员函数的后面加一个const(若函数的声明和定义是分开的,就声明和定义后面都需要加const)就可以将this指针改为(const Date*)类型。
再如下:
一般的类对象可以调用const成员函数,这属于权限缩小,是可以被允许的。

成员函数原则:

1.能定义成const的成员函数都应该定义成const,这样const对象和非const对象都可以调用。

2.要修改成员变量的成员函数,不能定义成const。(例如++运算符重载里面可能会改变成员变量day、month、year,而const成员函数的this指针是(const Date*)类型,看const位置就知道是解引用不能修改,也就是成员变量不能被修改。)。

3.注意<<、>>运算符重载后面不能用const修饰,因为在后面用const修饰的是*this,而这两个运算符重载不是成员函数,不存在this指针。

4.普通成员函数和const成员函数的this指针类型不同,所以是可以构成函数重载的。

六、默认成员函数-取地址操作符重载

实现如下:

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

虽然看起来函数名一样,但参数类型不一样,因为下者后面被const修饰了,所以this指针是(const Date*)类型,而上者this指针是(Date*)类型,所以参数类型不一样,可以构成重载。

注意:该成员函数时默认采用函数,若没有显示定义,编译器会自动生成默认成员函数。所以平时&可以直接用。

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

成工小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值