言简意赅:对象也可以做加减乘除等运算。
对象,也可以说是结构体,怎么做到像 C 里的运算符那样运算方便呢。有问题就会有方法。再自定义一个函数,然后根据相应的运算符重载一下,就可以实现对应功能了。
这个知识点可以说很重要,因为他实现了像日期类对象等可以直接加减的运算,大大加强了效率。
对象并没有平时常用运算符(只有赋值可以用),所以要自己一个一个敲出来。
一等:
我们先看第一种:
class Data
{
public:
Data(int year = 1, int month = 0, int day = 0)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
bool operator==(const Data& d1, const Data& d2)
{
return d1._year == d2._year
&& d1._month == d2.month //报错 访问错误
&& d1._day == d2._day;
}
int main()
{
Data d1(2023,5,2);
Data d2(2023,5,2);
return 0;
}
根据上面的错位,所以一般运算符重载的函数都是放在类里。像这样:
class Data
{
public:
Data(int year = 1, int month = 0, int day = 0)
{
_year = year;
_month = month;
_day = day;
}
bool operator==(const Data& d1, const Data& d2)
{
return d1._year == d2._year
&& d1._month == d2.month
&& d1._day == d2._day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Data d1(2023,5,2);
Data d2(2023,5,2);
return 0;
}
可是直接放里呢,又会说 E0344 此运算符函数的参数太多 原因呢,就和拷贝构造函数一样,是带有隐形参数的,就是赋值对象,就是主比较对象,我愿意叫他主对象。所以写法就是这样:
class Data
{
public:
Data(int year = 1, int month = 0, int day = 0)
{
_year = year;
_month = month;
_day = day;
}
bool operator==(const Data& d)
{
return _year == _year
&& _month == _month
&& _day == _day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Data d1(2023,5,2);
Data d2(2023,5,2);
cout << d1.operator==(d2) << endl;
return 0;
}
接下来呢,就说下需要注意的地方:
00xx00:.* :: sizeof ?: . 这五个运算符是不能重载的
00xx01:不能创建新的操作符
00xx02:必须有一个类类型参数
00xx03:含义不能改变
00xx04:参数少一 隐藏参数this
二等:
=:
现在再说下相等 = 也就是赋值
Data& operator=(const Data& d)
{
if (this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
这个if判断呢,就是防止有人让自己等于自己,这里再说下隐藏参数的问题,就是第一个参数是this,被隐藏了,所以传参和写参数时直接从第二个开始写就可以了。
++/--:
这里需要注意的最后一个点呢就是++,因为++有前置的,也有后置的。在写的时候函数的写法是一样的。所以我们可以做这样一个处理,让这个函数构成重载:
Data& operator++() //前置++
Data operator++(int) //后置++
这里明显看出两个区别,先说 int 效果就是让函数构成重载,并没有实质意义,第二个区别 & 前置++是先++在返回,可以把参数直接带回去,后置呢,是先返回再++,所以不能直接带回去,建立一个变量带回去。 -- 也是同理,其他类型也是如此。
三等:
<</>>:
先说流插入(<</cout),平时用流插入的时候,可以自动识别类型去直接输出,具体原因如下:
cout.operator<<(i) // int
cout.operator<<(d) // double
再回来看这个重载是怎么玩的
class Data
{
public:
Data(int year = 1, int month = 0, int day = 0)
{
_year = year;
_month = month;
_day = day;
}
bool operator==(const Data& d)
{
return _year == _year
&& _month == _month
&& _day == _day;
}
void operator<<(ostream& out)
{
out << _year << " " << _month << " " << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Data d1(2023,5,2);
Data d2(2023,5,2);
cout << d1.operator==(d2) << endl;
//cout << d1;
d1.operator<<(cout);
return 0;
}
运行结果如下
发现他并不能像平时那么使用,而是调用,原因呢 也很简单,就是需要私有里的数据,那有没有把他拿出来使用同时还能访问私有的方法呢,方法 自然就有 (站着 还能把钱赚了)
class Data
{
friend void operator<<(ostream& out, const Data& d)
{
out << d._year << " " << d._month << " " << d._day << endl;
}
public:
Data(int year = 1, int month = 0, int day = 0)
{
_year = year;
_month = month;
_day = day;
}
bool operator==(const Data& d)
{
return _year == _year
&& _month == _month
&& _day == _day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Data d1(2023,5,2);
Data d2(2023,5,2);
//cout << d1.operator==(d2) << endl;
cout << d1;
//d1.operator<<(cout);
return 0;
}
设置成友元函数就行了,you are my friend ,但是这样就少了一种功能:
cout << d1 << d2 << endl
原因呢,就是在返回值这里,没有返回值,怎么能连续插入呢
class Data
{
friend ostream& operator<<(ostream& out, const Data& d)
{
out << d._year << " " << d._month << " " << d._day << endl;
return out;
}
public:
Data(int year = 1, int month = 0, int day = 0)
{
_year = year;
_month = month;
_day = day;
}
bool operator==(const Data& d)
{
return _year == _year
&& _month == _month
&& _day == _day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Data d1(2023,5,2);
Data d2(2023,5,2);
//cout << d1.operator==(d2) << endl;
//cout << d1;
//d1.operator<<(cout);
cout << d1 << d2 << endl;
return 0;
}
大家自行测试就好了。
然后是流提取,有了流插入,流提取就好说多了。
大家直接结合cplusplus看代码就行了,注意 d 的const。
class Data
{
friend ostream& operator<<(ostream& out, const Data& d)
{
out << d._year << " " << d._month << " " << d._day << endl;
return out;
}
friend istream& operator>>(istream& in, Data& d)
{
in >> d._year >> d._month >> d._day;
return in;
}
public:
Data(int year = 1, int month = 0, int day = 0)
{
_year = year;
_month = month;
_day = day;
}
bool operator==(const Data& d)
{
return _year == _year
&& _month == _month
&& _day == _day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Data d1(2023,5,2);
Data d2(2023,5,2);
//cout << d1.operator==(d2) << endl;
//cout << d1;
//d1.operator<<(cout);
cout << d1 << d2 << endl;
return 0;
}