前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++笔记:运算符重载

C++笔记:运算符重载

作者头像
DioxideCN
发布2022-08-05 19:50:26
1.2K0
发布2022-08-05 19:50:26
举报
文章被收录于专栏:用户4480853的专栏

C++笔记:运算符重载

引言

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

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

运算符重载

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

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

运算符重载和方法

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

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

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

代码语言:javascript
复制
Complex Complex::operator+(Complex &c2){……}
c3=c1 + c2; //c3=c1.operator+(c2);

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

代码语言:javascript
复制
Complex operator+(Complex &c1, Complex &c2) {……}
c3 =  c1 + c2; //c3= operator+(c1, c2);

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

重载运算符的规则

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

运算符符号

运算符含义

.

成员访问运算符

.*

成员指针访问运算符

::

域运算符

sizeof

长度运算符

?:

条件运算符

  • 运算符重载不能改变运算符的运算对象(即操作数)的个数、优先级和结合性。
  • 重载的运算符必须和用户自定义类型的对象一起使用,其参数至少应有一个是类对象(或类对象的引用)。

重载双目运算符

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

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

重载单目运算符

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

重载流运算符

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

  1. 输入/输出流运算符只能重载为友元函数。
代码语言:javascript
复制
friend istream & operator>>(istream &input, Complex  &c);
friend ostream & operator<<(ostream &output, const Complex &c);

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

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

复数类案例

代码语言:javascript
复制
#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;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • C++笔记:运算符重载
    • 引言
      • 运算符重载
        • 运算符重载和方法
          • 用成员函数或友元函数重载运算符的对比(以双目运算符+为例)
        • 重载运算符的规则
          • 重载双目运算符
          • 重载单目运算符
          • 重载流运算符
        • 小结:C++运算符重载原则
          • 复数类案例
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档