目录
实践出真知,这篇文章直接实践几个例子来理解一下运算符重载,关于运算符重载的基础知识这里就不介绍了,挖个坑以后补充。
1.Array类
实现
#include<iostream>
using namespace std;
class Array {
friend ostream& operator<<(ostream& , const Array&);
friend istream& operator>>(istream& , Array&);
private:
int size;
int* ptr;
public:
Array(int si = 10) {
size = si > 0 ? si : 10;
ptr = new int[si];
for (int i = 0; i < si; i++)
ptr[i] = 0;
}
Array(const Array& a) {
size = a.size;
ptr = new int[size];
for (int i = 0; i < size; i++)
ptr[i] = a.ptr[i];
}
~Array() {
delete[]ptr;
}
const int getSize() {
return size;
}
Array operator=(const Array& a) { //跟拷贝构造函数还是有区别的
if (this != &a) {
if (size != a.size) {
delete[] ptr;
ptr = new int[a.size];
size = a.size;
}
for (int i = 0; i < size; i++)
ptr[i] = a.ptr[i];
}
return *this;
}
bool operator==(const Array& a) const{
bool isSame = true;
if (size != a.size)
isSame = false;
else {
for (int i = 0; i < size; i++) {
if (ptr[i] != a.ptr[i])
isSame = false;
}
}
return isSame;
}
int &operator[](int i) { //返回值可能要作为左值的时候,要加引用在类型后
if (i < 0 || i >= size){
cerr << "out_of_range";
exit(EXIT_FAILURE);}
return ptr[i];
}
int operator[](int i)const { //再写一个不做左值的版本注意后面加const
if (i < 0 || i >= size) {
cerr << "out_of_range";
exit(EXIT_FAILURE);
}
return ptr[i];
}
};
istream& operator>>(istream& input, Array& a) {
for (int i = 0; i < a.size; i++) {
input >> a.ptr[i];
}
return input;
}
ostream& operator<<(ostream& output, const Array& a){
for (int i = 0; i < a.size; i++)
output << a.ptr[i] << " ";
return output;
}
重载了包括[],=,==,<<和>>在内的运算符,初步实现了Array类,
测试:
int main() {
Array a(4);
cout << "Please input a:" << endl;
cin >> a;
cout << "a: " << a<<endl;
Array b(a);
cout << "After copy a, b: " << b;
cout <<endl<< "a = b ? : " << (a == b) << endl;
Array c = a;
cout << "After c=a,c: " << c << endl;
cout << "test []: " ;
for (int i = 0; i < 4; i++) {
cout << a[i]<<" ";
}
cout << endl;
}
Please input a:
4 6 3 8
a: 4 6 3 8
After copy a, b: 4 6 3 8
a = b ? : 1
After c=a,c: 4 6 3 8
test []: 4 6 3 8
2.Date类
实现
#include<iostream>
using namespace std;
class Date {
friend ostream& operator<<(ostream& o, const Date& d);
private:
int month;
int day;
int year;
public:
Date(int m=1, int d=1, int y=1990);
void setDate(int, int, int);
Date& operator++(); //左值++,相当于++a
Date operator++(int); //右值++,相当于a++
Date operator+(int);
bool isleapyear();
bool endOfMonth(int);
static const int days[];
void selfinc();
};
const int Date::days[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
Date::Date(int m , int d , int y ) {
setDate(m, d, y);
}
void Date::setDate(int m, int d, int y) {
month = m > 0 && m < 13 ? m : 1;
year = y > 1990 && y < 2100 ? y : 1990;
if (month == 2 && isleapyear()) {
day = d > 0 && d < 29 ? d : 1;
}
else {
day = d > 0 && d < 30 ? d : 1;
}
}
Date& Date::operator++() {
selfinc();
return *this;
}
Date Date::operator++(int) {
Date temp = *this;
selfinc();
return temp;
}
Date Date::operator+(int add) {
for (int i = 0; i < add; i++)
selfinc();
return *this;
}
bool Date::isleapyear() {
if (year % 400 == 0 || year % 100 != 0 && year % 4 == 0)
return true;
else
return false;
}
bool Date::endOfMonth(int day) {
if (month == 2 && isleapyear())
return day == 29;
else
return day == days[month];
}
void Date::selfinc() {
if (!endOfMonth(day))
day++;
else {
if (month < 12){
month++;
day = 1;
}
else {
month = 1;
day = 1;
year++;
}
}
}
ostream& operator<<(ostream& o, const Date& d) {
o << d.month << "/" << d.day << "/" << d.year << endl;
return o;
}
注意这里对++的重载有两种,一种是放在左边,另一种放在右边,放在左边返回的是自己,放在右边返回的是一个新的date对象;因此放在左边的++是需要返回值做做左值的,所以要加&。
测试
int main() {
Date d(4, 15, 2001);
Date d1(2, 28, 2000);
d1.selfinc();
cout << "After d1 slef-increase,d: " << d1 << endl;
cout << "judge d1 is or not leap year :" << d1.isleapyear() << endl;
Date d3 = d1 + 20;
cout << "After d3=d1+20,d3 : " << d3;
Date d2 = d1++;
cout << "After d2=d1++ ,d1: " << d1 << " d2 :" << d2 << endl;
Date d4 = ++d1;
cout << "After d4=++d1 ,d1 : " << d1 << " d4 : " << d4 << endl;
Date d5(12, 29, 2022);
d5 = d5 + 20;
cout << "d5: " << d5 << endl;
}
After d1 slef-increase,d: 2/29/2000
judge d1 is or not leap year :1
After d3=d1+20,d3 : 3/20/2000
After d2=d1++ ,d1: 3/21/2000
d2 :3/20/2000
After d4=++d1 ,d1 : 3/22/2000
d4 : 3/22/2000
d5: 1/18/2023
放点运算符重载知识点: