zoukankan      html  css  js  c++  java
  • 【C++】运算符重载

    运算符重载,主要是简化类类型运算,能够让我们对类对象直接用运算符进行运算。基本语法:

    类型 operator 运算符(参数列表){ ... }
    Complex operator+(Complex var1, Complex var2){ ... }

    简单地说,就是给类对象定义自己的加减乘除等等操作符。同时,作为为了类对象的操作而重载的运算符,它是类的成员函数,或者含有至少一个类类型参数,例如:

    (VS2013)

    另外,重载运算符分两种①重载运算符是类的成员函数;②重载运算符不是类的成员函数,简单地说就是重载定义在类的内部还是外部,这两种情况是有很大区别的,例如,我自己定义的一个复数Complex类,并为其重载加法运算符:

    class Complex
    {
    public:
        int a, b;
        void input(string s){
            int v1 = 0;
            int i = 0;
            while (s[i] != '+'){
                v1 = v1 * 10 + s[i] - '0';
                i++;
            }
            while (s[i] == ' ' || s[i] == '+' || s[i] == 'i'){
                i++;
            }
            int v2 = 0;
            while (i<s.length()){
                v2 = v2 * 10 + s[i] - '0';
                i++;
            }
            a = v1;
            b = v2;
        }
    
        /*========== 重载运算符为类成员函数 =============*/
        Complex operator+(Complex var){  //参数列表里只有一个参数,this被绑定到左侧运算对象
                                        //即第一个运算对象是this
            int a1 = a;   // a1 = this->a
            int b1 = b;
            int a2 = var.a;
            int b2 = var.b;
            Complex sumResult;
            sumResult.a = a1 + a2;
            sumResult.b = b1 + b2;
            return sumResult;
        }
        /*===============================================*/
    };
    
    /*========== 重载运算符不是类成员函数 =============*/
    Complex operator+(Complex var1, Complex var2){  //基本形式与函数定义相同
        int a1 = var1.a;
        int b1 = var1.b;
        int a2 = var2.a;
        int b2 = var2.b;
        Complex sumResult;
        sumResult.a = a1 + a2;
        sumResult.b = b1 + b2;
        return sumResult;
    }
    /*===============================================*/

    那么,在重载运算符的时候,如何选择将其声明为非成员函数还是声明为类成员函数呢?

    • 赋值(=),下标([]),调用(()),成员访问(->)必须是成员函数;
    • 复合赋值运算符和形如递增、递减和解引用等改变对象状态或与类型密切相关的运算符,一般定义为成员函数(非必须);
    • 具有对称性运算符可能转换任一端运算对象,如算术(加减乘除etc)、相等性、关系和位运算符等,通常定义为非成员函数。

    另外,如果参数含有类对象的混合表达式,必须定义成非成员函数。

    (C++ primer P493)

    运算符 note  
    输出<<  一般第一个形参是非常量ostream对象的引用,不要打印换行符 必须是非成员函数
    输入>>  第一个参数为读取流的引用,第二个参数是要读进去的非常量对象的引用,得检查读入是否成功 必须是非成员函数
    算术+-*/  一般,形参为常量引用 可以是非成员函数
    相等==  定义了==,应该也要有一个!= 可以是非成员函数
    小于< 不是每个类都能定义一个< 可以是非成员函数
    赋值=  要先销毁被赋值对象(左侧运算对象)当前的内存空间,再创建新空间存放新的赋值,返回被赋值对象的引用 必须是成员函数
    复合赋值 +=、-=  返回左侧运算对象的引用 一般是成员函数
    下标[]  返回所访问元素的引用(这样[]就可以出现在赋值运算符的任意一端);最好同时定义[]的常量版本和非常量版本 必须是成员函数

    另外还有几个重载比较复杂的:

    1、递增++/递减--运算符:

    • 要同时定义前置版本和后置版本;
    • 需要调用check函数检验对象是否有效;
    • 后置版本接受一个额外int类型形参(不被使用),需要在递增/递减对象之前记录之前的状态(后置递增返回值还是递增之前的值),后置版本要调用前置版本完成;
    • 显示调用:
      • 前置:p.operator++()【等价于++p】;
      • 后置:p.operator++(0)【等价于p++】

    2、成员访问运算符*、->:

    3、函数调用运算符():

  • 相关阅读:
    什么是首次适应算法,该算法的特点是什么?
    用上、下界防护方法是如何实现界地址保护?在硬件上需要什么支持?
    什么是存储保护?
    什么是静态地址重定位,它需要什么支持?什么是动态地址重定位,他需要什么支持?静态地址重定位与动态地址重定位有什么区别?
    什么是逻辑地址,什么是物理地址,为什么要进行二者的转换工作?
    三个进程共享四个同类资源,这些资源的分配与释放只能一次一个。已知每一个进程最多需要两个资源,试问,该系统会发生死锁吗?为什么?
    试举出一种一种避免死锁的发生的方法,并说明为什么能避免死锁的发生?
    产生死锁的原因是什么?产生死锁的必要条件是什么?
    什么是死锁,试举例说明?
    说出两种一笔调度的算法,并说出这两种移臂调度算法的定义。
  • 原文地址:https://www.cnblogs.com/Chilly2015/p/5423107.html
Copyright © 2011-2022 走看看