zoukankan      html  css  js  c++  java
  • 14. 运算符重载(二)

    3. 递增运算符重载(++、--)

    作用:通过重载递增运算符,实现自己的整型数据
    注意:前置递增返回引用,后置递增返回值

    //  首先你要搞明白 前置++ 与 后置++ 区别;
    int a = 10;
    cout << ++a <<endl; // 11
    cout << a <<endl; // 11
    int b = 10;
    cout << b++ <<endl; // 10
    cout << b <<endl; // 11
    

    #include <iostream>
    using namespace std;
    // 自定义整型
    class Myinteger
    {
          friend ostream& operator<<(ostream& cout,Myinteger myint)
    public:
          Myinteger()
          {
                m_NNum = 0;
          }
          //重载前置 ++ 运算符
          // 返回引用为了已知对一个数据进行递增操作,详情请看 test01 中的第一个和第二个 cout
          Myinteger& operator++ ()  //注意返回值类型
          {
                m_Num++;
                return *this;  // 这里还是返回自己,this是指针进行解引用
          }
    
          //重载后置 ++ 运算符
          //int 代表占位参数,可以用于区分前置和后置递增
          //这里为什么返回的是值?是由于 temp 是局部对象
          Myinteger operator++ (int)  //注意返回值类型
          {
                Myinteger temp = *this;  // 先记录当时的结果
                m_Num++;  //后递增
                return temp;  //将记录的结果进行返回
          }
    
    private:
          int m_Num;
    };
    
    // 重载左移运算符
    ostream& operator<<(ostream& cout,Myinteger myint)
    {
          cout << myint.m_Num;
          return cout; 
    }
    
    void test01()
    {
          Myinteger myint;
          cout << ++(++ myint) << endl;
          cout << myint <<endl;
    }
    
    void test02()
    {
          Myinteger myint;
          cout << myint++ << endl;
          cout << myint <<endl;
    }
    int main()
    {
          test01();
          test02();
          system("pause");
          return 0;
    }
    

    4. 赋值运算符重载

    C++ 编译器至少给一个类添加 4 个函数

    • 默认构造函数(无参,函数体为空)
    • 默认析构函数(无参,函数体为空)
    • 默认拷贝构造函数,对属性进行值拷贝
    • 赋值运算符 operator=,对属性进行拷贝
      如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题
    class Person 
    {
    public:
          Person (int age)
          {
                m_Age = new int (age); /开辟堆区,堆区需要由程序员手动释放
          }
          int *m_Age;
          ~Person()  //堆区的数据在析构中释放,注意堆区的内存重复释放程序崩溃的问题,利用深拷贝来解决浅拷贝带来的问题
          {
                if(m_Age != NULL)
                {
                      delete m_Age;
                      m_Age = NULL;
                }
          }
          //重载 赋值运算符
           Person& operator=(Person &p)  //如果返回的是值的话会创建一个副本占用内存,用引用才是返回真正的自身
          {
                //编译器提供浅拷贝   m_Age = p.m_Age;
                //我们应该先判断是否由属性在堆区,如果由先释放干净,再进行深拷贝操作
                if(m_Age != NULL)
                {
                      delete m_Age;
                      m_Age = NULL;
                }
                m_Age=new int (*p.m_Age);
                return *this; //返回对象本体
          }
    };
    void test01()
    {
          Person p1(18);
          Person p2(20);
          Person p3(30);
    
          p3=p2=p1;
          cout << "p1的年龄:"<< *p1.m_Age <<endl;
          cout << "p2的年龄:"<< *p2.m_Age <<endl;
          cout << "p3的年龄:"<< *p3.m_Age <<endl;
    }
    int main()
    {
          test01();
          system("pause");
          return 0;
    }
    


    5. 关系运算符的重载(== 或 != )

    作用:重载关系运算符,可以让两个自定义类型对象进行对比操作

    #include <iostream>
    using namespace std;
    #include <string>
    
    //重载关系运算符
    class Person 
    {
    public:
          Person(string name,int age)
          {
                m_Name = name;
                m_Age = age;
          }
          string m_Name;
          int m_age;
          
          //重载 == 号
          bool operator==(Person &p)
          {
                if(this->m_Name == p.m_Name && this->m_Age == p.m_Age)
                      return true;
          }
          return false;
          bool operator!=(Person &p)
          {
                if(this->m_Name == p.m_Name && this->m_Age == p.m_Age)
                      return false;
          }
          return true;
    };
    void test01()
    {
          Person p1("Tom",18);
          Person p2("Jerry",18);
          if(p1==p2)
          {
                cout<< "p1 和 p2 是相等的" << endl;
          }
          else 
          {
                cout << "p1 和 p2是不相等的" << endl;
          }
    
          if(p1!=p2)
          {
                cout<< "p1 和 p2 是不相等的" << endl;
          }
          else 
          {
                cout << "p1 和 p2是相等的" << endl;
          }
    }
    int main()
    {
          test01();
          system("pause");
          return 0;
    }
    


    6. 函数调用运算符重载

    • 函数调用运算符()也可以重载
    • 由于重载后使用的方式非常像函数的调用,因此称为仿函数
    • 仿函数没有固定写法,非常灵活
    #include <iostream>
    using namespace std;
    #include <string>
    
    class Myprint
    {
    public:
          //函数调用运算符重载
          void operator ()(string test)
          {      
                cout << test endl;
          }
          
    };
    class Myadd
    {
    public:
          //函数调用运算符重载
          int operator ()(int num1,int num2)
          {      
                return num1 + num2;
          }
          
    };
    void test01()
    {
          Myprint myprint;
          myprint("hello world"); //由于重载后使用的方式非常像函数的调用,因此称为仿函数
    }
    //仿函数没有固定写法,非常灵活
    void test02()
    {
          Myadd myadd;
          int ret = myadd(100,100);
          cout << "ret =" <<ret <<endl;
          
          //类型() ————> 匿名函数对象:当前行执行完立即释放
          cout << Myadd()(100,100) << endl;
    }
    int mian()
    {
          test01();
          test02();
          system("pause");
          return 0;
    }
    
  • 相关阅读:
    windows下运行命令行mysql,提示mysql不是内部命令,解决办法
    XML和HTML的区别
    BZOJ4695 最假女选手(势能线段树)
    BZOJ5312 冒险(势能线段树)
    洛谷P3959 宝藏(NOIP2017)(状压DP,子集DP)
    区间子集最大/最小异或和问题(线性基,树上差分)
    线性基模板(线性基)
    分数模板(C++模板)
    洛谷P2516 [HAOI2010]最长公共子序列(LCS,最短路)
    组合数学知识要点
  • 原文地址:https://www.cnblogs.com/BY1314/p/12982797.html
Copyright © 2011-2022 走看看