少年恃险若平地,独倚长剑凌清秋。这篇文章主要讲述[ C++ ] 类与对象(下)日期类Date补充及流提取和流插入运算符重载相关的知识,希望能为你提供帮助。
【[ C++ ] 类与对象(下)日期类Date补充及流提取和流插入运算符重载】
文章引入:
1.const成员1.1 const修饰类的成员函数在日期类中,我们实例化一个普通对象,普通对象调用成员函数要传参,传给隐含的this指针。普通对象调用Print(),要把d1的地址传给this指针,那如果是const对象呢?
在之前我们实现了日期类Date,其中还有一些小的细节本篇将进行补充。?
const对象取地址是const Date* ,所指向的内容不能被修改,此时如果只是一个普通的成员函数是不能编译通过的。因此此时我们要将this指针变成const this *,但是我们没发改,因此我们在后面加const
此时普通对象可以调用(权限缩小),const修饰的对象也可以调用(权限不变)。
Q: 思考下面的几个问题:
总结:建议成员函数中不修改成员变量的成员函数,都可以加上const
好处:普通对象和const对象都可以调用
const-> const 权限一样
普通-> const 权限的缩小
A:
1. const对象可以调用非const成员函数吗?
2. 非const对象可以调用const成员函数吗?
3. const成员函数内可以调用其它的非const成员函数吗?
4. 非const成员函数内可以调用其它的const成员函数吗?
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 < iostream> .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< < d1,调用完后应该会有一个返回值,这个返回值再去做下一次流插入的左操作数,下一次流插入的左操作数还应该是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已经较为完整了,大家可以自己实现测试练习。
(本篇完)
推荐阅读
- Java基础之方法引用(JDK1.8新特性)
- Java基础之Stream流(JDK1.8新特性)
- HarmonyOS - 实现多设备协同
- 看漫画漫画柜mhgui,Python爬虫之神奇的eval,附赠一个压缩模块
- AI+科学计算-昇思MindSpore都给我们带来哪些惊喜()
- 数据仓库进阶 - 01 《阿里大数据之路》第二篇 数据模型篇
- Java 集合系列07--- HashMap详细介绍(源码解析)----新
- #导入Word文档图片# Linux下IO多路复用: Selectpollepoll
- 流水线中如何获取代码库分支信息