目 录CONTENT

文章目录

C++笔记:运算符重载

Dioxide-CN
2022-03-09 / 0 评论 / 1 点赞 / 24 阅读 / 5,395 字
温馨提示:
本文最后更新于 2022-04-22,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

C++笔记:运算符重载

引言

函数重载就是对一个已有的函数赋予新的含义,使之实现新功能,做到“一名多用”。
运算符也可以重载,在C++标准库中也使用了大量的运算符重载。例如:

  • << 既是左移运算符,又是流输出运算符。
  • >> 既是右移运算符,又是流输入运算符。
  • + 能实现int、float、double类型的不同的运算。同样的,可对“+”运算符进行重载,实现两个对象的加法运算。

运算符重载

运算符重载是通过定义函数实现的,这种函数称为运算符重载函数,它通常是类的成员函数或者友元函数

  • 运算符重载函数的一般格式为:
    函数类型 operator 运算符名称 (形参列表) { 对运算符的重载处理 }
  • 例如:
    Complex& operator=(const Complex &right)

运算符重载和方法

  1. 类的成员函数作为运算符重载函数
  2. 类的友元函数作为运算符重载函数
class Complex  //复数类
{
  public:
    //使用成员函数重载运算符+
    Complex operator+(Complex &right);
    //使用友元函数重载运算符+
    friend Complex operator+(Complex &left, Complex &right);
  private:
    double real;  // real number
    double imag;  // imaginary number
};

用成员函数或友元函数重载运算符的对比(以双目运算符+为例)

重载函数为成员函数时,可以少写一个函数的参数(通过this指针直接访问当前对象)。

Complex Complex::operator+(Complex &c2){……}
c3=c1 + c2; //c3=c1.operator+(c2);

由运算符左侧的对象调用运算符重载函数。
将双目运算符重载为友元函数时,形参表列中必须有两个参数,形参的顺序任意。

Complex operator+(Complex &c1, Complex &c2) {……}
c3 =  c1 + c2; //c3= operator+(c1, c2);

在使用运算符时,其左侧的操作数作为第一个实参,其右侧的操作数作为第二个实参。

重载运算符的规则

C++ 不允许用户自己定义新的运算符,只能对已有的 C++ 运算符进行重载。
C++ 中绝大部分的运算符允许重载。不能重载的运算符只有5个

运算符符号 运算符含义
. 成员访问运算符
.* 成员指针访问运算符
:: 域运算符
sizeof 长度运算符
?: 条件运算符
  • 运算符重载不能改变运算符的运算对象(即操作数)的个数、优先级和结合性。
  • 重载的运算符必须和用户自定义类型的对象一起使用,其参数至少应有一个是类对象(或类对象的引用)。

重载双目运算符

例: 声明一个复数类Complex,有实部和虚部组成,重载运算符“+” “-” “+=”,“-=” ,实现复数的相应运算。

  1. 具有自赋值的二元运算符建议重载为成员函数
    += -= /= *= &= |= ~= %= >>= <<=
  2. 其他二元运算符建议重载为友元函数
    + - * / > < == & ||

重载单目运算符

  1. 所有的一元运算符建议重载为成员函数
    ++ -- & ! ~
  • ++ 为前置运算时 i++ ,运算符重载函数的一般格式为:
类型 & operator++( )  ,
Complex & operator++();  //前置运算符 ++c
  • ++ 为后置运算时 ++i ,运算符重载函数的一般格式为:
类型 operator++(int) //多了一个int型形参
Complex operator++(int index);  //后置运算符 c++

重载流运算符

C++ 中用 cout <<cin >> 对标准类型数据进行输入输出。其中,cincout 分别是输入流类 istream 和输出流类 ostream 的对象。在头文件 iostream.h 中已经对 <<>> 进行了重载,使之作为流输入运算符和流输出运算符。

  1. 输入/输出流运算符只能重载为友元函数
friend istream & operator>>(istream &input, Complex  &c);
friend ostream & operator<<(ostream &output, const Complex &c);

小结:C++运算符重载原则

(1)赋值运算符只能重载为成员函数
= () [] ->
(2)所有的一元运算符建议重载为成员函数
++ -- & ! ~
(3)含有赋值操作的二元运算符建议重载为成员函数
+= -= /= *= &= |= ~= %= >>= <<=
(4)其他二元运算符建议重载为友元函数
+ - * / > < == & ||
(5)输入/输出流运算符只能重载为友元函数
<< >>

复数类案例

#include <iostream>
#include <math.h>
using namespace std;
//复数类 ------------------------------------------------------------------------
class Complex
{
    private:
        double real;
        double imag;
    public:
        //友元重载
        friend Complex operator+(const Complex &left, const Complex &right);
        friend Complex operator-(const Complex &left, const Complex &right);
        friend istream& operator>>(istream &input, Complex &c);
        friend ostream& operator<<(ostream &output, const Complex &c);

        Complex():real(0),imag(0){};       //1. 缺省构造
        Complex(double real, double imag); //2. 有参构造
        Complex(const Complex &c);         //3. 拷贝构造
        ~Complex(){};                      //4. 析构

        Complex& operator++();                     //++i
        Complex operator++(int);                   //i++
        Complex& operator+=(const Complex &right); //+=
        Complex& operator-=(const Complex &right); //-=
        bool operator>=(const Complex &right);     //>=
        bool operator<=(const Complex &right);     //<=
};
//成员重载 ----------------------------------------------------------------------
Complex& Complex::operator++()
{
    //++i
    ++real;
    ++imag;
    return *this;
}
Complex Complex::operator++(int)
{
    //i++
    Complex temp = *this;
    ++real;
    ++imag;
    return temp;
}
Complex& Complex::operator+=(const Complex &right)
{
    //+=
    real += right.real;
    imag += right.imag;
    return *this;
}
Complex& Complex::operator-=(const Complex &right)
{
    //-=
    real -= right.real;
    imag -= right.imag;
    return *this;
}
bool Complex::operator>=(const Complex &right)
{
    //>=
    if(imag == 0) return real >= right.real;
    if(real == 0) return imag >= right.imag;
    int __left__ = sqrt(pow(real,2)+pow(imag,2));
    int __right__ = sqrt(pow(right.real,2)+pow(right.imag,2));
    return (__left__ >= __right__);
}
bool Complex::operator<=(const Complex &right)
{
    //<=
    if(imag == 0) return real <= right.real;
    if(real == 0) return imag <= right.imag;
    int __left__ = sqrt(pow(real,2)+pow(imag,2));
    int __right__ = sqrt(pow(right.real,2)+pow(right.imag,2));
    return (__left__ <= __right__);
}
//友元重载 -----------------------------------------------------------------------
Complex operator+(const Complex &left, const Complex &right)
{
    //+
    Complex temp;
    temp.real = left.real + right.real;
    temp.imag = left.imag + right.imag;
    return temp;
}
Complex operator-(const Complex &left, const Complex &right)
{
    //-
    Complex temp;
    temp.real = left.real - right.real;
    temp.imag = left.imag - right.imag;
    return temp;
}
istream& operator>>(istream &input, Complex &c)
{
    //>>
    input >> c.real >> c.imag;
    return input;
}
ostream& operator<<(ostream &output, const Complex &c)
{
    //<<
    if((c.real == 0 && c.imag == 0) || (c.real != 0)) output << c.real;
    if(c.imag == 1) output << "+i";
    else if(c.imag == -1) output << "-i";
    else if(c.imag > 0)
    {
        if(c.real == 0) output << c.imag << "i";
        else output << "+" << c.imag << "i";
    }
    else if(c.imag < 0) output << c.imag << "i";
    else ;
    output << endl;
    return output;
}
//五大函数 -----------------------------------------------------------------------
Complex::Complex(double real, double imag)
{
    //2. 有参构造
    this->real = real;
    this->imag = imag;
}
Complex::Complex(const Complex &c)
{
    //3. 拷贝构造
    real = c.real;
    imag = c.imag;
}
//主函数 -------------------------------------------------------------------------
int main() {
    /**
     * @author Dioxide_CN
     * @date 2022.4.9
     */
    Complex c1, c2;

    cout << "请输入2个复数:";
    cin >> c1 >> c2;

    //TODO --> 调用重载运算符使用

    cout << ">=:" << (c1 >= c2) << endl;
    cout << "<=:" << (c1 <= c2) << endl;
    
    return 0;
}
1

评论区