C++运算符的重载
课题目标
了解多态性,掌握运算符重载的种类,形式,与体现方式,学会重载运算符
课题内容
面向程序设计的优势在于将派生类对象当基类对象一样处理,这就是多态和动态绑定。
多态的类型
分为专用多态(重载多态,强制多态),通用多态(包含多态,参数多态)。
重载多态:主要是函数与类的成员函数的重载和运算符重载。
一,运算符重载
运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同的行为。
二,运算符重载的多态意义
我们了解的运算符的功能“ + ”、“ - ”、“ * ”、“ / ”可能单一,但就不同数据类型进行相同的操作,这就是多态的体现。
三,运算符重载的语法形式:
返回类型 operator op(参数){ //对应操作 }
operator:关键字
op:函数名
四,运算符重载的方式体现
1)普通运算符重载(“ + ”、“ - ”、“ * ”、“ / ”等)
1 #include2 using namespace std; 3 4 class Complex 5 { 6 private: 7 double real,imag; 8 public: 9 Complex(double r = 0.0, double i = 0.0); 10 void Print(); 11 Complex operator+(Complex a); 12 Complex operator-(Complex a); 13 14 }; 15 16 Complex::Complex(double r, double i) 17 { 18 real = r; 19 imag = i; 20 } 21 22 Complex Complex::operator+(Complex a) 23 { 24 Complex temp; 25 temp.real = real + a.real; 26 temp.imag = imag + a.imag; 27 return temp; 28 } 29 30 Complex Complex::operator-(Complex a) 31 { 32 Complex temp; 33 temp.real = real - a.real; 34 temp.imag = imag - a.imag; 35 return temp; 36 } 37 38 void Complex::Print() 39 { 40 cout <<real; 41 if(imag > 0) 42 cout << "+"; 43 if(imag != 0) 44 cout << imag << "i" <<endl; 45 } 46 47 int main() 48 { 49 Complex c1(1.1, 2.2), c2(3.3, 4.4),total; 50 total = c1 + c2; 51 total.Print(); 52 total = c1 - c2; 53 total.Print(); 54 return 0; 55 } 56
2)前置运算符重载("++"、"--")
1 类名 operator++() //前缀方式 2 类名 operator--() //前缀方式
1 #include2 #include 3 using namespace std; 4 5 class Point 6 { 7 private: 8 int x,y; 9 public: 10 Point(int i = 0, int j = 0); 11 Point operator++(); 12 Point operator--(); 13 void Print(); 14 15 }; 16 17 Point::Point(int i, int j) 18 { 19 x = i; 20 y = j; 21 } 22 23 void Point::Print() 24 { 25 cout << "(" << x << "," << y << ")" <<endl; 26 } 27 28 Point Point::operator--() 29 { 30 --x; 31 --y; 32 return *this; 33 } 34 Point Point::operator++() 35 { 36 ++x; 37 ++y; 38 return *this; 39 } 40 int main() 41 { 42 Point ob1(1, 2); 43 cout << "ob1:"; 44 ob1.Print(); 45 cout << "++ob1: "; 46 ++ob1; 47 cout << "ob1:"; 48 ob1.Print(); 49 cout << "--ob2:"; 50 ob1.Print(); 51 return 0; 52 }
3)后置运算符重载("++"、"--")
后缀与前缀的区别就在于(int),当然所实现的功能也有所不同
1 类名 operator ++(int) //后缀方式 2 类名 operator --(int) //后缀方式
1 #include2 using namespace std; 3 4 class Point 5 { 6 private: 7 int x,y; 8 public: 9 Point(int i = 0, int j = 0); 10 Point operator++(int); 11 Point operator--(int); 12 void Print(); 13 }; 14 15 Point::Point(int i, int j) 16 { 17 x = i; 18 y = j; 19 } 20 21 void Point::Print() 22 { 23 cout << "(" << x << "," << y << ")" <<endl; 24 } 25 26 Point Point::operator--(int) 27 { 28 Point temp = *this; 29 x--; 30 y--; 31 return temp; 32 } 33 Point Point::operator++(int) 34 { 35 Point temp = *this; 36 x++; 37 y++; 38 return temp; 39 } 40 41 int main() 42 { 43 Point ob1(1, 2),; 44 cout << "ob1:"; 45 ob1.Print(); 46 cout << "ob1++: "; 47 ob1++; 48 cout << "ob1--:"; 49 ob1--; 50 ob1.Print(); 51 return 0; 52 }
4)插入运算符重载(">>")、提取运算符重载("<<")
1 #include2 using namespace std; 3 4 class Distance 5 { 6 private: 7 int feet; // 0 到无穷 8 int inches; // 0 到 12 9 public: 10 Distance(){ 11 feet = 0; 12 inches = 0; 13 } 14 Distance(int f, int i){ 15 feet = f; 16 inches = i; 17 } 18 friend ostream &operator<<( ostream &output, const Distance &D ) 19 { 20 output << "F : " << D.feet << " I : " << D.inches; 21 return output; 22 } 23 24 friend istream &operator>>( istream &input, Distance &D ) 25 { 26 input >> D.feet >> D.inches; 27 return input; 28 } 29 }; 30 31 int main() 32 { 33 Distance D1(11, 10), D2(5, 11), D3; 34 cout << "Enter the value of object : " << endl; 35 cin >> D3; 36 cout << "First Distance : " << D1 << endl; 37 cout << "Second Distance :" << D2 << endl; 38 cout << "Third Distance :" << D3 << endl; 39 return 0; 40 }
五,重载运算符的方式
第一种就是把运算符重载函数作为类内成员函数,他可以通过this 指针自由的访问本类的数据成员,因此可以少些一个参数
例:Complex operator +(Complex &);
第二种就是用普通函数重载(注意需要在类内声明为友元函数)
例:friend Complex operator +(Complex &a1,Complex &a2);//声明为友元函数
双目运算符重载为友元函数时,由于友元函数不是该类的成员函数,因此在函数的形参列表里必须有两个参数,不能省略
六,运算符重载的注意事项
1)并不是所有的运算符都可以重载。能够重载的运算符包括:
+ - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> <<= >>= == != <= >= && || ++ -- , ->* -> () [] new new[] delete delete[]
2)重载不能改变运算符的优先级和结合性。
3)重载不会改变运算符的用法
4)运算符重载函数不能有默认的参数,否则就改变了运算符操作数的个数
实验例题
定义一个RMB类 Money,包含元、角、分三个数据成员,友元函数重载运算符‘+’(加)
和 ‘-’(减),实现货币的加减运算
例如:
请输入元,角,分:
2 3 4
请输入元,角,分:
3 7 3
和:6元0角7分
差:-1元3角9分
解析:利用运算符重载'+''-',在函数中实现对yuan,jiao,fen的运算的重载,再在主函数通过运算符实现。
代码如下:
#includeusing namespace std; class Money { private: int yuan, jiao, fen; bool flag; //标志位,0表示钱数为正,1表示钱数为负 -> 默认结果的钱数为正 public: Money(); Money(int fg, int y=0, int j=0, int f=0): yuan(y), jiao(j), fen(f), flag(fg){} friend Money operator+(Money a, Money b); friend Money operator-(Money a, Money b); void display(); }; Money::Money() { flag = 0; cout << "请输入元、角 分:" <<endl; cin >> yuan >> jiao >> fen; } void Money::display() { if(flag==1) cout << '-'; cout << yuan << "元" << jiao << "角" << fen << "分" << endl; } //请用友元函数重载加/减,并要在类Money中声明为友元 //TODO重载加 类外定义Money类的+重载运算 Money operator+(Money a, Money b) { Money temp(0); // 将钱全部转化成分来计算 int money_a = a.yuan*100 + a.jiao*10 + a.fen*1; int money_b = b.yuan*100 + b.jiao*10 + b.fen*1; int res = money_a + money_b; // 因为是相加 故应该结果是正的 所以不用判断符号 但是相减时 结果可能为负 就要判断符号 temp.yuan = res/100; res = res % 100; temp.jiao = res/10; temp.fen = res % 10; // 返回结果对象 return temp; } //TODO重载减 类外定义Money类的-重载运算 Money operator-(Money a, Money b) { Money temp(0); // 将钱全部转化成分来计算 int money_a = a.yuan*100 + a.jiao*10 + a.fen*1; int money_b = b.yuan*100 + b.jiao*10 + b.fen*1; int res = money_a - money_b; // 因为是相减时 结果可能为负 就要判断符号 if(res < 0) { temp.flag = 1; res = -res; } temp.yuan = res/100; res = res % 100; temp.jiao = res/10; temp.fen = res % 10; // 返回结果对象 return temp; } int main() { Money m1, m2, m3(0), m4(0); //m3用来记录和,m4用来记录差 // + m3=m1+m2; cout<<"和:"; m3.display(); // - m4=m1-m2; cout<<"差:"; m4.display(); return 0; }