栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

[ C++ ] 类与对象(下)日期类Date补充及流提取和流插入运算符重载

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

[ C++ ] 类与对象(下)日期类Date补充及流提取和流插入运算符重载

文章引入:

在之前我们实现了日期类Date,其中还有一些小的细节本篇将进行补充。若您是首次访问日期类Date,可以看看上篇文章哦  [C++] 类与对象(中) --日期类Date

目录

1.const成员

1.1 const修饰类的成员函数

2.取地址及const取地址操作符重载 

3.流提取和流插入运算符重载

3.1流插入运算符重载

问题1:

问题2:

最终正确版本:

3.2流提取运算符重载

3.3测试 


 

1.const成员

1.1 const修饰类的成员函数

在日期类中,我们实例化一个普通对象,普通对象调用成员函数要传参,传给隐含的this指针。普通对象调用Print(),要把d1的地址传给this指针,那如果是const对象呢?

const对象取地址是const Date* ,所指向的内容不能被修改,此时如果只是一个普通的成员函数是不能编译通过的。因此此时我们要将this指针变成const this *,但是我们没发改,因此我们在后面加const

此时普通对象可以调用(权限缩小),const修饰的对象也可以调用(权限不变)。

总结:建议成员函数中不修改成员变量的成员函数,都可以加上const

好处:普通对象和const对象都可以调用   
const->const 权限一样
普通->const 权限的缩小

Q: 思考下面的几个问题:

1. const对象可以调用非const成员函数吗?

2. 非const对象可以调用const成员函数吗?

3. const成员函数内可以调用其它的非const成员函数吗?

4. 非const成员函数内可以调用其它的const成员函数吗?

A:

2.取地址及const取地址操作符重载 

类与对象第一节我们说类一共有6个默认成员函数,之前我们已经学习了4个了,现在我们一起来看看最后两个。(不是很重要,因为默认生成的就完全够用了)

class Date
{
public:
	Date* operator&()
	{
		return this;
	}

	const Date* operator&()const
	{
		return this;
	}
private:
	int _year; // 年
	int _month; // 月
	int _day; // 日
};

总结:这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如想让别人获取到指定的内容!

3.流提取和流插入运算符重载

在日期类的输入和输出中,有时我们想通过流提取和流插入运算符,我们还是要通过实现运算符重载解决这个问题。

内置类型是直接支持流插入和流提取的,并且是可以自动识别类型的。这也是因为运算符重载。这是为什么呢?

	//流插入 流提取
	int i = 1;
	double d = 2.2;
	cout << i;//自动识别类型
	cout << d;

这是因为cout和cin是全局的对象,他们包含在iostream头文件中,所以我们写C++程序要包#include .cin是istream的对象,cout是ostream的对象。因此它俩是两个类型,这个类型是库里面的,流插入和流提取的类型。

 我们平时使用时可以直接使用源自于常见的内置类型都重载了。因此cin和cout能够自动识别的原因是因为:函数重载

 因此刚刚的代码实际是这样的:

    int i = 1;
	double d = 2.2;
	//函数重载 std::ostream::operator<<
	//ostream& operator<<(int val);
	cout << i;//自动识别类型
	cout.operator<<(i);//实际是这个
	cout << d;

 但是我们这里是自定义类型怎么办呢?因此我们自己写一个就好了

3.1流插入运算符重载

问题1:
class Date
{
public:
	void operator<<(std::ostream& out)
	{
		out << _year << "-" << _month << "-" << _day << endl;
	}

private:
	int _year;
	int _month;
	int _day;
};

但是此时我们只能通过这种方式来进行访问。

由于成员函数第一个参数是隐含的this无法更改,因此我们写成全局的

写在类外有由于_year,_month,_day是私有的因此我们可以使用友元函数来访问。

class Date
{
	//友元函数
	//流提取
	friend void operator<<(std::ostream& out, const Date& d);
public:

private:
	int _year;
	int _month;
	int _day;
};

//由于成员函数是私有的 我们无法访问
//1.可以使用GetYear() GetMOnth() GetDay()接口 然后在外调用函数
//2.友元函数
void operator<<(std::ostream& out,const Date& d)
{
	out << d._year << "-" << d._month << "-" << d._day << endl;
}

此时我们发现是可以编译通过的。 

问题2:

如果我们想连续访问呢?

此时会先调用cout<

最终正确版本:
class Date
{
	//友元函数
	//流提取
	friend std::ostream& operator<<(std::ostream& out, const Date& d);
public:

private:
	int _year;
	int _month;
	int _day;
};

//由于成员函数是私有的 我们无法访问
//1.可以使用GetYear() GetMOnth() GetDay()接口 然后在外调用函数
//2.友元函数
std::ostream& operator<<(std::ostream& out,const Date&d)
{
	out << d._year << "-" << d._month << "-" << d._day << endl;
	return out;
}

3.2流提取运算符重载
class Date
{
	//友元函数
	//流提取
	friend std::ostream& operator<<(std::ostream& out, const Date& d);
	//流插入
	friend std::istream& operator>>(std::istream& in, Date& d);//Date要赋值修改 所以不能const
public:

private:
	int _year;
	int _month;
	int _day;
};

std::ostream& operator<<(std::ostream& out,const Date&d)
{
	out << d._year << "-" << d._month << "-" << d._day << endl;
	return out;
}
std::istream& operator>>(std::istream& in, Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}

3.3测试 
int main()
{


	Date d1, d2;
	cin >> d1;
	cout << d1;
	cin >> d2;
	cout << d2;

	return 0;
}

至此:我们的日期类Date已经较为完整了,大家可以自己实现测试练习。

(本篇完)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/971113.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号