【C++】类和对象--日期类Date补充及流提取、流插入
1. const成员
1.1 const修饰类的成员函数
在Date日期类中,我们实例化一个普通对象。而普通对象调用普通成员函数需要传参,传参传给隐藏的this指针,下面给出一个例子:
代码语言:javascript
AI代码解释
class Date
{
public:
Date(int year=0, int month=0, int day=0)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main() {
//这里实例化的是一个普通对象
Date d(2025, 8, 23);
//此时d(普通对象)调用Print
//传参给this指针
//也就是将d1的地址传给了this
d1.Print();
}
上面这种情况肯定是能够顺利运行的,但是如果实例化一个const对象呢,还能够顺利编译吗?
代码语言:javascript
AI代码解释
int main() {
const Date d2(2025, 8, 23);
d2.Print();
}
我们发现报错了:

这是因为将Date实例化为const,那么在调用Print()时,传入的地址类型应该是const Date *,但是this指针是Date的,那么这个转换是不被允许的(因为权限被放大了)。
那么我们第一反应的解决方案肯定就是将这类的this指针类型修改成const Date *,但是我们学过这个this指针是由编译器自动生成的,我们没有办法直接修改。所以C++的设计者这样解决:
代码语言:javascript
AI代码解释
//在成员函数参数列表后面加上const修饰
//起作用就相当于void Print(const Date * const this )
//这样一来这个传参过程就能够顺利进行了
void Print() const
{
cout << _year << "-" << _month << "-" << _day << endl;
}
总结:建议所有不修改成员变量的成员函数都加上const
- const -> const 权限大小不变
- 普通 -> const 权限变小(是编译器允许的)
Q:思考下面几个问题
- const对象可以调用非const成员函数吗?
- 非const对象可以调用const成员函数吗?
- const成员函数内可以调用其它的非const成员函数吗?
- 非const成员函数内可以调用其它的const成员函数吗?
A:答案
- 不能,权限被放大了
- 能,权限被缩小了
- 不能,权限被放大了
- 能,权限被缩小了
2. 取地址及const取地址操作符重载
前面讲到,一共有6个默认成员函数,我们已经学习了4个,现在我们来看一看剩下两个(并不是很重要,默认生成的即可):
代码语言:javascript
AI代码解释
class Date
{
public:
Date* operator&()
{
return this;
}
const Date* operator&() const
{
return this;
}
private:
int _year; // 年
int _month; // 月
int _day; // 日
};
总结:这两个运算符一般不需要重载,使用编译器默认生成的取地址重载即可。只有在一些特殊情况才需要重载,例如想要让用户看到指定的信息!
3. 流提取和流插入运算符重载
代码语言:javascript
AI代码解释
Date d2(2025, 8, 23);
cout << d2 << endl;
会报错:

显然我们想要完成自定义类的输入和输出,就要进行流提取、流插入的运算符的重载。
但是我们想一下,内置类型都是可以直接使用流提取和流插入运算符的,这似乎好像也是重载哦!
代码语言:javascript
AI代码解释
int i = 1;
double d = 2.2;
cout << i;//自动识别类型
cout << d;
我们深入了解一下:
cout 和 cin 是全局对象,他们包含在iostream头文件中,所以我们在写C++文件的时候会#include <iostream>。cin是istream的对象,cout是ostream的对象,istream和ostream是库中的流提取和流插入的两个类型。

而<<和>>能够识别不同的内置类型的真正原因就是,把所有内置类型都重载了:

所以其实真实的情况就是:


那么针对Date日期类这种自定义类型,我们也只需要重载一下就可以了。
更多推荐


所有评论(0)