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;
}
posted @ 2020-05-30 10:53  by1314  阅读(177)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end