运算符重载
Posted liubingyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了运算符重载相关的知识,希望对你有一定的参考价值。
题目描述:定义一个时间类,小时和分钟是其两个私有成员数据。输入一个起始时间和一个结束时间(起始时间早于结束时间),通过运算符重载-(减号),计算这两个时间相隔多少分钟。说明:这两个时间在同一天之内,且采用24小时计时分式,即从00:00-23:59。
输入格式: 测试输入包含若干测试用例,每个测试用例占一行。每个测试用例包括四个数,用空格间隔,每个数都是由两位数字组成,第一个数和第二个数分别表示起始时间的小时和分钟,第三个数和第四个数分别表示结束时间的小时和分钟。当读入一个测试用例是00 00 00 00时输入结束,相应的结果不要输出。
输出格式:对每个测试用例输出一行。输出一个数即可,表示两者之间间隔的分钟数。
输入样例:
12 11 12 58
00 13 16 00
09 07 23 59
00 00 00 00
输出样例:
47
947
892
#include<iostream> using namespace std; class Time private: int hour; int minute; public: Time(int h = 00, int m = 00) hour = h; minute = m; int friend operator- (Time p, Time q); ; int operator- (Time q, Time p) int c = 0; int d = 0; if (p.minute < q.minute|| p.minute == q.minute) d = q.hour - p.hour; c = q.minute - p.minute + 60 * d; return c; else d = q.hour - p.hour - 1; c = 60 + q.minute - p.minute + 60 * d; return c; int main() int a, b, c, d; while (cin >> a >> b >> c >> d) if (a == 00 && b == 00 && c == 00 && d == 00) break; int difference; Time p1(a, b); Time p2(c, d); difference = p2 - p1; cout << difference << endl; return 0;
运算符重载1
所谓重载,就是重新赋予新的含义。函数重载是对一个已有的函数赋予新的含义,使之实现新功能。
其实运算符也可以重载,实际上,我们常常在不知不觉之中使用了运算符重载。
运算符重载的方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现相应的运算。 也就是说,运算符重载是通过定义函数实现的。运算符重载实质上是函数的重载。
重载运算符的函数一般格式如下:
函数类型 operator 运算符名称(形参表列) { 对运算符的重载处理 }
例如我们可以重载运算符 + , 如下:
int operator+(int a, int b) { return (a – b); }
举个栗子:实现复数加法 (3, 4i)+ (5, -10i)= (8, -6i)
当我们还不知道重载,我们会这样做: complex.cpp
#include <iostream> class Complex { public: //两类构造函数情况 Complex();//第一类构造函数,无初始化 Complex(double r, double i);//第二类构造函数,有初始化 Complex complex_add(Complex &d); void print(); private: double real; double imag; }; Complex::Complex() { real = 0; imag = 0; } Complex::Complex(double r, double i) { real = r; imag = i; } Complex Complex::complex_add(Complex &d) { Complex c; c.real = real + d.real; c.imag = imag + d.imag; return c; } void Complex::print() { std::cout << "(" << real << ", " << imag << "i) "; } int main() { Complex c1(3, 4), c2(5, -10), c3; c3 = c1.complex_add(c2); std::cout << "c1 = "; c1.print(); std::cout << "c2 = "; c2.print(); std::cout << "c1 + c2 = "; c3.print(); return 0; }
结果:
c1 = (3, 4i) c2 = (5, -10i) c1 + c2 = (8, -6i) 请按任意键继续. . .
当我们朦胧懂得了重载,我们会这样做: complex2.cpp
#include <iostream> // 演示对运算符"+"进行重载达到目的! class Complex { public: Complex(); Complex(double r, double i); Complex operator+(Complex &d);//重载最好用类的函数的类型 void print(); private: double real; double imag; }; Complex::Complex() { real = 0; imag = 0; } Complex::Complex(double r, double i) { real = r; imag = i; } Complex Complex::operator+(Complex &d)//重载的实现程 { Complex c; c.real = real + d.real; c.imag = imag + d.imag; return c; } void Complex::print() { std::cout << "(" << real << ", " << imag << "i) "; } int main() { Complex c1(3, 4), c2(5, -10), c3; c3 = c1 + c2; std::cout << "c1 = "; c1.print(); std::cout << "c2 = "; c2.print(); std::cout << "c1 + c2 = "; c3.print(); return 0; }
我们在声明 Complex 类的时候对运算符进行了重载,使得这个类在用户编程的时候可以完全不考虑函数是如何实现的,直接使用 +, -, *, / 进行负数的运算即可。 其实,我们还可以对运算符重载函数 operator+ 改写得更简练一些:
Complex Complex::operator+(Complex &c2) { return Complex(real+c2.real, imag+c2.imag); }
一些规则:
- C++不允许用户自己定义新的运算符,只能对已有的C++运算符进行重载。
-
除了一下五个不允许重载外,其他运算符允许重载:
-
.(成员访问运算符)
-
.*(成员指针访问运算符)
-
::(域运算符)
-
sizeof(尺寸运算符)
-
?:(条件运算符)
- 重载不能改变运算符运算对象(操作数)个数。
- 重载不能改变运算符的优先级别。
-
重载不能改变运算符的结合性。
-
重载运算符的函数不能有默认的参数。
-
重载的运算符必须和用户定义的自定义类型的对象一起使用,其参数至少应该有一个是类对象或类对象的引用。(也就是说,参数不能全部都是C++的标准类型,这样约定是为了防止用户修改用于标准类型结构的运算符性质)。
运算符重载函数作为类友元函数:
不知道刚刚有没有这样的疑问:”+”运算符是双目运算符,为什么刚刚的例子中的重载函数只有一个参数呢?
解答:实际上,运算符重载函数有两个参数,但由于重载函数是 Complex 类中的成员函数,有一个参数是隐含着的,运算符函数是用 this 指针隐式地访问类对象的成员。
return Complex(real+c2.real, imag+c2.imag); return Complex(this->real+c2.real, this->imag+c2.imag); return Complex(c1.real+c2.real, c1.imag+c2.imag);
那么例子中的 c1 + c2,编译系统把它解释为: c1.operator+(c2)
即通过对象 c1 调用运算符重载函数,并以表达式中第二个参数(运算符右侧的类对象c2)作为函数实参。
运算符重载函数除了可以作为类的成员函数外,还可以是非成员函数:放在类外,做 Complex 类的友元函数存在:complex3.cpp
#include <iostream> // 演示对运算符"+"进行重载达到目的! class Complex { public: Complex(); Complex(double r, double i); friend Complex operator+(Complex &c, Complex &d);//放在类外,做 Complex 类的友元函数存在 void print(); private: double real; double imag; }; Complex::Complex() { real = 0; imag = 0; } Complex::Complex(double r, double i) { real = r; imag = i; } // 注意,这里作为友元函数,不属于Complex,记得别写 :: 咯! Complex operator+(Complex &c, Complex &d) { return Complex(c.real+d.real, c.imag+d.imag); } void Complex::print() { std::cout << "(" << real << ", " << imag << "i) "; } int main() { Complex c1(3, 4), c2(5, -10), c3; c3 = c1 + c2; std::cout << "c1 = "; c1.print(); std::cout << "c2 = "; c2.print(); std::cout << "c1 + c2 = "; c3.print(); return 0; }
为什么把运算符函数作为友元函数呢?
因为运算符函数要访问 Complex 类对象的成员,如果运算符函数不是 Complex 类的友元函数,而是一个普通的函数,它是没有权力访问 Complex 类的私有成员的。
由于友元的使用会破坏类的封装,因此从原则上说,要尽量将运算符函数作为成员函数。
课后作业:
请听题: 重载运算符 ”+”, ”-”, ”*”, ”/” 实现有理数的加减乘除运算。
- 如 1/8 + 7/8 = 1
- 如 1/8 – 7/8 = -6/8
- 如 1/8 * 7/8 = 7/64
- 如 1/8 / 7/8 = 1/7
以上是关于运算符重载的主要内容,如果未能解决你的问题,请参考以下文章