Day_06 运算符重载

        运算符重载,就是赋予运算符具有操作自定义类型数据功能。运算符重载的实质就是函数调用,它的格式是:返回值   函数名(参数1,参数2...),但是又不同于普通函数。 运算符重载函数的函数名是用 operator+运算符 组成的。返回值是运算完成后的值决定的。

1.运算符重载     

          运算符重载有两个方式:1.友元函数的方式重载

                                                  2.类的成员函数的方式重载

(1). 友元函数的方式重载

        在类中申明运算符重载时需要在前缀加上friend修饰,友元函数方式的运算符重载,该函数是不属于类的,所以函数参数的个数等于运算符操作数的个数。

Class MM{
public:
    MM(int age):age(age){ };

    //友元函数的方式重载运算符
    friend MM operator+(MM m1,MM m2){
        return MM(m1.age+m2.age);
    }

    void print(){
    cout<< age <<endl;
    }
protected:
    int age;
};
int main(){
    MM m1(19);
	MM m2(20);
    //隐式调用运算符重载函数
	MM m3 = m2 + m1;
    //显式调用运算符重载函数
    MM m3 = operator+(m1, m2);
    m3.print();
    return 0;
}

        上述代码中,有关于调用运算符重载函数的两种方式(显示调用和隐式调用)。显示调用更好的说明了运算符重载的本质就是函数调用 。

  (2).类的成员函数的方式重载

        把运算符重载的函数变成类的成员函数,由于采用成员函数的形式重载,是属于类的,所以函数的参数就等于操作数-1(因为他的本质是通过对象调用,所以可以少写一个操作数)。

class MM{
public:
	MM(int age) :age(age){ };
    //友元函数的方式重载
	friend MM operator+(MM m1, MM m2);
	void print(){
		cout << age << endl;
	}
    //类的成员函数的方式重载
	MM operator-(MM m2){
		return (this->age - m2.age);
	}
protected:
	int age;
};
MM operator+(MM m1, MM m2)
{
	return MM(m1.age + m2.age);
}
int main(){
	MM m1(19);
	MM m2(20);
	MM m3 = operator+(m1, m2);

    //类的成员函数方式的显示调用运算符重载
	MM m4 = m1.operator-(m2);
    //类的成员函数方式的隐示调用运算符重载
	MM m4 = m1 - m2;
	m3.print();

}

 2.流重载

        关于我们输入输出流运算符<<   >>的重载只能采用友元函数的方式来重载。cin 和 cout 都是 istream类和 ostream类的一个对象。之所以我们能用<< >>运算符来操作 istream 和 ostream来输入输出,就是因为istream 和 ostream 类中已经对流运算做了重载 。

class MM{
public:
	MM(string name = " ", int age = 18) :name(name), age(age){

	}
        //根据cout cin 能连续输出输入 可以推断流重载返回的是流对象的引用
	 	friend istream&  operator>>(istream& in, MM& mm){
		
			return in;
		}
		 friend ostream&  operator<<(ostream out, MM mm){

			 return out;
		}
protected:
	string name;
	int age;
};

        根据cout cin 能连续输出输入 可以推断流重载返回的是流对象的引用。

3.++ --运算符重载

        前置运算符和后置运算符相比,后置运算符多了一个无用的参数int

class MM 
{
public:
	MM(string name ,int age):name(name),age(age){}

	MM operator++(int)	//后置运算符 需要一个无用参数 充当标记
	{
		//return MM(name,age++);
	}

	MM operator++()    //前置运算符,不需要int
	{
		return MM(name, ++age);
	}
protected:
	string name;
	int age;
};

4.类的对象的隐式转换

        operator除了重载运算符,还能对类进行隐式转换 : operator + 需要被转换的类型

如下:

class MM 
{
public:
	MM(string name ,int age):name(name),age(age){}

	//类的对象的隐式转换  operator
	operator int() 
	{
		return age;
	}
protected:
	string name;
	int age;
};
int main(){
    MM mm("xx",28);

    //进行了类的隐式转换
    int MMage=mm;
    
    return 0;
}

总结:

  • = () -> [] 只能采用类的成员函数形式重载

  • 流重载采用友元方式

  • .    .*   ?:    :: 不能重载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目描述 定义一个学生类Student,包含该学生的姓名、出生年、月、日 ,重定义 “-”号实现两个学生之间相差多少天的比较。并利用重载的“-”运算符,求所有学生中年龄相差最小的两个人的名字以及相差天数。 输入 第一行:输入所需要输入的学生个数; 第二行开始,依次输入每个学生的姓名、出生年、月、日。 输出 输出年龄相差最小的两个人的名字以及相差天数,名字的输出顺序按输入的先后,天数大于等于0。 输入样例 3 Tom 1995 1 1 Joe 1995 2 28 Jimmy 1996 1 8 输出样例 Tom和Joe年龄相差最小,为58天。 代码实现 ```cpp #include <iostream> #include <string> #include <cmath> #include <algorithm> using namespace std; class Student { public: string name; int year, month, day; int days;//存储距离1970年1月1日的天数 Student() {} Student(string name, int year, int month, int day) { this->name = name; this->year = year; this->month = month; this->day = day; days = getDays(year, month, day); } int getDays(int year, int month, int day) { int days = 0; int months[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; for(int i = 1970; i < year; i++) { if((i % 4 == 0 && i % 100 != 0) || i % 400 == 0) { days += 366;//闰年 } else { days += 365;//平年 } } for(int i = 1; i < month; i++) { if(i == 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)) { days += 29;//闰年的2月 } else { days += months[i];//其他月份 } } days += day;//加上天数 return days; } int operator - (const Student &s) { return abs(days - s.days); } }; int main() { int n; cin >> n; Student s[n]; for(int i = 0; i < n; i++) { string name; int year, month, day; cin >> name >> year >> month >> day; s[i] = Student(name, year, month, day); } int minDiff = 0x7fffffff; string name1, name2; for(int i = 0; i < n; i++) { for(int j = i + 1; j < n; j++) { int diff = s[i] - s[j]; if(diff < minDiff) { minDiff = diff; name1 = s[i].name; name2 = s[j].name; } } } cout << name1 << "和" << name2 << "年龄相差最小,为" << minDiff << "天。" << endl; return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值