WHCSRL 技术网

C++运算符重载

前言

         最近学习了c++的运算符重载,由于针对不同的运算符进行重载和不同的重载方式都有需要注意的点,下面分别对重载方式(成员函数,友元函数)和重载内容(普通运算符,以++运算符为例)分别进行整理

1、重载方式:

       1)成员函数进行运算符重载要求第一个参数一定是自定义对象返回类型要是自定义对象。所以通常用于相同类型对象之间的运算。

      2)友元函数实现运算符重载相对比较灵活,能实现不同数据类型之间的运算。但是定义函数时注意第一个形参对应运算符的左边操作数,第二个形参对应运算符的右边操作数,顺序不可反

2、++运算符重载

      i++和++i运算符重载函数的区别是:i++重载函数多了一个int型参数

3、流插入运算符重载  “<<”   和流提取运算符重载  “>>”

 friend ostream & operator<<(ostream &out, Complex& c1);
 friend
istream& operator>>(istream& in, Complex& c1);

      1)    流运算符重载只能使用友元函数实现。

      2)流插入 和流提取重载函数的第一个参数分别固定为ostream 和istream对象:

      3)流插入 和流提取重载函数返回类型为ostream 和istream类型

      4)重载函数里面是用传进来的ostream (istream)对象去调用输出(输入)流

下面进行代码示例



一、两种重载方式

1、成员函数实现

  1. class Complex {
  2. private:
  3. double real;
  4. double imag;
  5. public:
  6. Complex() {
  7. real = 0;
  8. imag = 0;
  9. }
  10. Complex(double r, double m) {
  11. real = r;
  12. imag = m;
  13. }
  14. double getReal();
  15. double getImag();
  16. void display();
  17. //成员函数定义 两个Complex对象相加的运算
  18. Complex operator+(Complex& c1);
  19. };

 注意点:
     1、返回值必须是Compare对象
     2、 + 的左边要求是Compare对象,所以它可以实现(1 + 2i) + 2的运算,但是不能实现2 + (1 + 2i)的运算,因为这里左边是int,下面通过友元可以解决这个问题。

 

        

2、使用友元函数

  1. class Complex {
  2. private:
  3. double real;
  4. double imag;
  5. public:
  6. Complex() {
  7. real = 0;
  8. imag = 0;
  9. }
  10. Complex(double r, double m) {
  11. real = r;
  12. imag = m;
  13. }
  14. double getReal();
  15. double getImag();
  16. void display();
  17. //友元函数定义 两个Complex对象相加的运算
  18. friend Complex operator+(Complex& c2, Complex& c3);
  19. //下面是实现Complex对象与int数据的运算
  20. //1、Complex对象+int 因为第一个参数是Complex对象,所以也可以设置为成员函数,只把int传进来
  21. friend Complex operator+(Complex& c1, int n);
  22. //Complex operator+(int n); //相当于 this.operator+(n) 针对当前对象与n进行加运算
  23. //2、int+Complex对象 因为第一个参数是int,故不可以使用成员函数
  24. friend Complex operator+(int n, Complex& c1);
  25. };

注意点:
       1、第一个形参的数据类型,对应+左边的操作数类型,第二个形参的类型对应右边的操作数的类型。
       2、返回值可以不是Complex对象


二、运算符重载


1.代码示例

      重载++运算符实现,秒数达到60时,秒数清零,分数加一

   1)Time1.h

  1. #pragma once
  2. #include "Date.h"
  3. class Time1 {
  4. int hour; //时
  5. int minute; //分
  6. int sec; //秒
  7. public:
  8. void set_time();
  9. void show_time();
  10. Time1(int, int, int);
  11. Time1 operator++(); //前加加 ++i
  12. Time1 operator++(int); //后加加 i++ 后加为了区别前加 多加了个int型参数
  13. };

     2)Time1.cpp

  1. #include <iostream>
  2. #include "Time1.h"
  3. #include "Date.h"
  4. #include "student.h"
  5. using namespace std;
  6. Time1::Time1(int h,int m,int s):hour(h), minute(m), sec(s){}
  7. //++i运算符重载
  8. Time1 Time1::operator++() {
  9. if (++sec >= 60) { //先把59+1然后判断是否大于60
  10. sec = 0;
  11. minute += 1;
  12. }
  13. return *this;
  14. }
  15. //i++运算符重载,注意多了个int参数与++i重载函数进行区分
  16. Time1 Time1::operator++(int) {
  17. int t = ++sec; //判断秒数加一后的数值
  18. if (t >= 60) {
  19. sec = 0;
  20. minute += 1;
  21. }
  22. return *this;
  23. }
  24. //time对象初始化
  25. void Time1::set_time() { //注意类函数的限定符写在函数类型后面
  26. cout << "请输入时分秒:" << endl;
  27. cin >> hour;
  28. cin >> minute;
  29. cin >> sec;
  30. }
  31. // time对象显示
  32. void Time1::show_time() {
  33. cout << hour<<"-";
  34. cout << minute << "-";
  35. cout << sec;
  36. }

三、重载流插入运算符和流提取运算符

  1. class Complex {
  2. private:
  3. double real;
  4. double imag;
  5. public:
  6. Complex() {
  7. real = 0;
  8. imag = 0;
  9. }
  10. Complex(double r, double m) {
  11. real = r;
  12. imag = m;
  13. }
  14. double getReal();
  15. double getImag();
  16. void display();
  17. //重载流插入运算符 输出 <<
  18. friend ostream & operator<<(ostream &out, Complex& c1);
  19. //重载流提取运算符 输入>>
  20. friend istream& operator>>(istream& in, Complex& c1);
  21. };
  22. ostream &operator<<(ostream & out, Complex& c1) {
  23. //注意这里使用ostream对象 out去调用的输出流
  24. out << c1.real << "+" << c1.imag << "i";
  25. return out; //返回去当前out对象可以连续再调用重载函数
  26. }
  27. istream& operator>>(istream& in, Complex& c1) {
  28. cout << "实部:";
  29. //注意这里使用istream对象in 去调用的输入流
  30. in >> c1.real;
  31. cout << "虚部:";
  32. in >> c1.imag;
  33. return in;//返回去当前in对象可以连续再调用重载函数
  34. }
  35. int main(){
  36. Complex c1,c2,c3;
  37. cin >> c1; // 这里的cin对象相当于第一个形参in operator>>(out,c1)
  38. cout << c1;
  39. //下面分两次调用了重载函数 因为重载函数返回的是ostream (istream)对象,
  40. //可连续向输出流(输入流)插入信息
  41. cin >> c1>>c2;
  42. cout << c1 <<" "<< c2;
  43. }

    注意: 

        1、 流运算符的重载只能使用友元函数的形式实现。因为定义成员函数实现要求第一个参数是自定义对象。而实际调用的时候第一个参数是ostream (istream)对象。

      2、重载函数返回的是ostream (istream)对象,所以可以连续向输入输出流插入信息



总结

1、重载方式:

       1)成员函数进行运算符重载要求第一个参数一定是自定义对象。返回类型也要是中自定义对象。所以通常用于相同类型对象之间的运算。

      2)友元函数实现运算符重载相对比较灵活,能实现不同数据类型之间的运算。但是定义函数时注意第一个形参对应运算符的左边操作数,第二个形参对应运算符的右边操作数,顺序不可反。

2、++运算符重载

      i++和++i运算符重载函数的区别是:i++重载函数多了一个int型参数

3、流插入运算符重载  “<<”   和流提取运算符重载  “>>”

 friend ostream & operator<<(ostream &out, Complex& c1);
friend istream& operator>>(istream& in, Complex& c1);

      1)    流运算符重载只能使用友元函数实现。

      2)流插入 和流提取重载函数的第一个参数分别固定为ostream 和istream对象:

      3)流插入 和流提取重载函数返回类型为ostream 和istream对象。

      4)重载函数里面是用传进来的ostream (istream)对象去调用输出(输入)流

推荐阅读