🌈个人主页:羽晨同学
💫个人格言:“成为自己未来的主人~”
相较于printf和scanf而言,C++中的cout,和cin是有一定的局限性的(因为要兼容C语言)。
所以,我们在竞赛当中,为了提高效率,通常会运用这样的一句代码:
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
将二者之间的匹配机制关掉。
下面,我们来看一下下面的这一段代码:
#include<iostream>
using namespace std;
class Date
{
public:
Date(int year = 2000, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
void operator<<(ostream& out)
{
out << _year << "年" << _month << "月" << _day << "日" << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
//ios_base::sync_with_stdio(false);
//cin.tie(nullptr);
//cout.tie(nullptr);
Date d1(2024,4,4);
d1 << cout;
return 0;
}
在这段代码当中,我们用赋值符运算重载定义了<<,并在下面用d1<<cout进行了调用。
但是你会发现一个很不好的问题,那就是此时是d1<<cout,而我们常用到的是cout<<d1;
这个是为什么呢?
那就涉及到了我们前面讲过的编译器默认的*this指针,这是是占第一个的,所以,我们上传的只能占第二个,而形参必须要和实参的顺序对应,所以,我们只能写成这样。
那有办法解决吗?当然有,那就是设置成全局函数。
ostream& operator<<(ostream& out, const Date& d)
{
out << d._year << "年" << _month << "月" << _day << "日" << endl;
return out;
}
这样就可以根据我们的需要来修改参数的顺序。
istream& operator>>(istream& in, Date& d)
{
in >> d._year>>d._month>>d._day;
return in;
}
但是这样有一个很严重的问题,那就是_year等变量是私有空间当中,不能进行访问,那我们这个时候应该怎么办呢?
我们可以使用友元来应对这种情况。
friend ostream& operator<<(ostream& out, Date& d);
friend istream& operator>>(istream& in, const Date& d);
这样子就不会受到私有空间的约束。
接下来,我们再来看一段代码
void Date::Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
void TestDate5()
{
Date d1(2022, 5, 5);
d1.Print();
}
这段代码当中,显然不会出现问题。
void Date::Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
void TestDate5()
{
const Date d1(2022, 5, 5);
d1.Print();
}
但是在这段代码当中,就会出现报错。
这是出现了权限的放大,我们知道,在
这个当中,会有一个*this指针,我们将&d1也就是const Date*传入,由Date*接收,很明显,出现了权限的放大。
所以,我们需要堆Date*进行范围的限制,那我们应该怎么做呢,
void Date::Print() const
{
cout << _year << "-" << _month << "-" << _day << endl;
}
void TestDate5()
{
const Date d1(2022, 5, 5);
d1.Print();
}
在函数声明和定义后面都加上一个const,这样,就不会出现报错。