美文网首页
C++ 运算符重载

C++ 运算符重载

作者: 付凯强 | 来源:发表于2022-08-13 22:29 被阅读0次

运算符重载将重载的概念扩展到运算符上,允许赋予C++运算符多种含义。实际上,很多C++运算符已经重载。将*运算符用于地址,将得到存储在这个地址中的值;但将它用于两个数字时,得到的将是它们的乘积。C++根据操作数的数目和类型来决定采用哪些操作。
C++允许将运算符重载扩展到用户定义的类型。例如:允许使用+将两个对象相加。编译器将根据操作数的数目和类型决定使用哪个加法定义。
重载运算符让代码看起来更自然。不过重载运算符,需使用被称为运算符函数的特殊函数形式。格式如下:

operatorop(argument-list)

例如:operator+()重载+运算符,operator()重载运算符。op必须是有效的C++运算符,不能虚构一个新的符号。
当然最重要的是,当调用的时候,可以使用简便的运算符表示法,而不必使用笨拙的函数表示法。
我们用示例来讲解下上述内容。

计算时间的示例

假如我上午花费在简书上的时间是2小时8分钟,下午花费在简书的时间是3小时23分钟,则总共花费了多长时间在抖音上呢?我们用程序来表示下。

//
// Created by fukaiqiang on 22-8-13.
//

#ifndef OPERATOR_TIME_H
#define OPERATOR_TIME_H

class Time {
private:
    int hours;
    int minutes;
public:
    Time();
    Time(int h,int m = 0);
    void AddMin(int m);
    void AddHr(int h);
    void Reset(int h = 0,int m = 0);
    Time Sum(const Time& t) const;
    void Show() const;
};

#endif //OPERATOR_TIME_H

Time类提供了用于调整和重新设置时间、显示时间、将两个时间相加的方法。请注意,当总的分钟数超过59时,AddMin()和Sum()方法是如何使用整数除法和求模运算符来调整minutes和hour值的。另外这里只使用了iostream和cout,且只使用了一次,因此使用std::cout比导入整个名称空间更经济。

//
// Created by fukaiqiang on 22-8-13.
//

#include "Time.h"
#include <iostream>

Time::Time() {
    hours = minutes = 0;
}

Time::Time(int h,int m) {
    hours = h;
    minutes = m;
}

void Time::AddMin(int m) {
    minutes += m;
    hours += minutes / 60;
    minutes %= 60;
}

void Time::AddHr(int h) {
    hours += h;
}

void Time::Reset(int h, int m) {
    hours = h;
    minutes = m;
}

Time Time::Sum(const Time& t) const {
    Time sum;
    sum.minutes = minutes + t.minutes;
    sum.hours = hours + t.hours + sum.minutes /60;
    sum.minutes %= 60;
    return sum;
}

void Time::Show() const {
    std::cout << hours << "hours, " << minutes << "minutes";
}

来看下Sum()函数的代码。注意参数是引用,但是返回类型却不是引用。将参数声明为引用的目的是为了提高效率。如果按值传递Time对象,代码的功能将相同,但传递引用,速度将更快,使用的内存将更少。
另外。返回值不能是是引用。因为函数将创建一个新的Time对象sum,来表示另外两个Time对象的和。返回对象将创建对象的副本,而调用函数可以使用它。然后,如果返回类型为Time&,则引用的将是sum对象。但由于sum对象是局部变量,在函数结束时将被删除,因此引用将指向一个不存在的对象。使用返回类型Time意味着程序将在删除sum之前构造它的拷贝,调用函数将得到该拷贝。
警告:不要返回指向局部变量或临时对象的引用。函数执行完毕后,局部变量和临时对象将消失,引用将指向不存在的数据。

#include <iostream>
#include "Time.h"

int main() {
    using std::cout;
    using std::endl;
    Time planning;
    Time coding(2,40);
    Time fixing(5,55);
    Time total;

    cout << "planning time = ";
    planning.Show();
    cout << endl;

    cout << "coding time = ";
    coding.Show();
    cout << endl;

    cout << "fixing time = ";
    fixing.Show();
    cout << endl;

    total = coding.Sum(fixing);
    cout << "coding.Sum(fixing) = ";
    total.Show();
    cout << endl;

    return 0;
}
planning time = 0hours, 0minutes
coding time = 2hours, 40minutes
fixing time = 5hours, 55minutes
coding.Sum(fixing) = 8hours, 35minutes

为示例添加加法运算符

把Sum替换为operator+,如下所示

Time operator+(const Time& t) const;
Time Time::operator+(const Time& t) const {
    Time sum;
    sum.minutes = minutes + t.minutes;
    sum.hours = hours + t.hours + sum.minutes /60;
    sum.minutes %= 60;
    return sum;
}
total = coding.operator+(fixing);

和调用Sum函数一样,operator+也是由Time对象调用,将第二个Time对象作为参数,并返回一个Time对象,因此可以像调用Sum函数一样调用operator+函数。

引入运算符表示法

    total = coding.operator+(fixing);

可以表示为

    total = coding + fixing;

这种运算符表示法也将调用operator+函数。
注意:

  1. 在运算符表示法中,运算符左侧的对象是调用对象,运算符右边的对象是作为参数被传递的对象。
  2. 当调用重载运算符时,编译器通过把所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。选择最合适的重载运算符的过程,称为重载决策。

几种运算符重载

一元运算符 - 负号重载

#include <iostream>
using namespace std;

class Distance
{
...
public:
...
    void operator-()
    {
        feet = -feet;
        inches = -inches;
    }
};
int main()
{
    D1.operator-();                     // 取相反数
    D2.operator-();                     // 取相反数
    -D1;                     // 取相反数
    -D2;                     // 取相反数
...
    return 0;
}

二元运算符 + 加号重载

本文的主示例即是重载二元运算符 + 加号的示例。

关系运算符 < 小于号重载

        bool operator <(const Distance& d)
        {
            if(feet < d.feet)
            {
                return true;
            }
            if(feet == d.feet && inches < d.inches)
            {
                return true;
            }
            return false;
        }
    if (D1 < D2) {
        cout << "D1 is less than D2 " << endl;
    } else {
        cout << "D2 is less than D1 " << endl;
    }

递增递减运算符重载

    // 重载前缀递增运算符( ++ )
    Check operator ++ ()
    {
        Check temp;
        temp.i = ++i;
        return temp;
    }
 
    // 重载后缀递增运算符( ++ )
    Check operator ++ (int)
    {
        Check temp;
        temp.i = i++;
        return temp;
    }
obj1 = ++obj;
obj1 = obj++;

递减雷同,就不再赘述。

赋值运算符重载

    void operator=(const Distance &D )
    {
        feet = D.feet;
        inches = D.inches;
    }
D1 = D2;

下标运算符重载

      int& operator[](int i)
      {
          if( i >= SIZE )
          {
              cout << "索引超过最大值" <<endl; 
              // 返回第一个元素
              return arr[0];
          }
          return arr[i];
      }
cout << "A[12] 的值为 : " << A[12]<<endl;

类成员访问运算符 -> 重载

类成员访问运算符( -> )可以被重载,但它较为麻烦。它被定义用于为一个类赋予"指针"行为。运算符 -> 必须是一个成员函数。如果使用了 -> 运算符,返回类型必须是指针或者是类的对象。

class Ptr{
   //...
   X * operator->();
};

类 Ptr 的对象可用于访问类 X 的成员,使用方式与指针的用法十分相似。例如:

void f(Ptr p )
{
   p->m = 10 ; // (p.operator->())->m = 10
}

语句 p->m 被解释为 (p.operator->())->m

输入输出运算符

      friend ostream &operator<<( ostream &output, 
                                       const Distance &D )
      { 
         output << "F : " << D.feet << " I : " << D.inches;
         return output;            
      }
 
      friend istream &operator>>( istream  &input, Distance &D )
      { 
         input >> D.feet >> D.inches;
         return input;            
      }
   Distance D1(11, 10), D2(5, 11), D3;
 
   cout << "Enter the value of object : " << endl;
   cin >> D3;
   cout << "First Distance : " << D1 << endl;
   cout << "Second Distance :" << D2 << endl;
   cout << "Third Distance :" << D3 << endl;
Enter the value of object :
70
10
First Distance : F : 11 I : 10
Second Distance :F : 5 I : 11
Third Distance :F : 70 I : 10

可重载运算符/不可重载运算符

可重载运算符/不可重载运算符

参考

https://www.runoob.com/cplusplus/cpp-overloading.html
C++ Primer PLUS (第 6 版)中文版

相关文章

  • 第十一章 使用类

    运算符重载 运算符重载是一种形式的C++多态。运算符重载将重载的概念扩展到运算符上,允许赋予C++运算符多种含义。...

  • 1.2.15_C++ 关系运算符重载

    C++ 重载运算符和重载函数 C++ 语言支持各种关系运算符( < 、 > 、 <= 、 >= 、 == 等等),...

  • C++ 运算符重载

    运算符重载将重载的概念扩展到运算符上,允许赋予C++运算符多种含义。实际上,很多C++运算符已经重载。将*运算符用...

  • C++运算符重载

    C++运算符重载的实质:运算符重载的实质就是函数重载或函数多态。运算符重载是一种形式的C++多态。目的在于让人能够...

  • C++运算符重载-下篇 (Boolan)

    C++运算符重载-下篇 (Boolan) 本章内容:1. 运算符重载的概述2. 重载算术运算符3. 重载按位运算符...

  • C++运算符重载-上篇 (Boolan)

    C++运算符重载-上篇 (Boolan) 本章内容:1. 运算符重载的概述2. 重载算术运算符3. 重载按位运算符...

  • C++ 重载运算符

    C++重载运算符

  • C++重载

    重载 C++语言规定: 重载的运算符要保持原运算符的意义。只能对已有的运算符重载,不能增加新的运算符。重载的运算符...

  • 1.2.17_C++ ++ 和 -- 运算符重载

    C++ 重载运算符和重载函数 递增运算符( ++ )和递减运算符( -- )是 C++ 语言中两个重要的一元运算符...

  • C++运算符重载详解

    运算符重载规则 1.被重载的运算符必须是已经存在的C++运算符,不能重载自己创建的运算符; 2.运算符被重载之后,...

网友评论

      本文标题:C++ 运算符重载

      本文链接:https://www.haomeiwen.com/subject/keeqgrtx.html