C++语言之重载运算符()/[]/++/->等运算符

C++语言之重载运算符()/[]/++/->等运算符

文章链接:http://blog.csdn.net/qq_16628781/article/details/72629722

知识点

  1. 重载()运算符;
  2. 重载[]运算符;
  3. 重载++和->运算符;
  4. 新名词记录{operator}

概述

operator操作符一文包括两种用法,一种是operator overloading(操作符重载),一种是operator casting(操作隐式转换)。

这是C++和pascal扩展运算符功能的方法,虽然样子古怪,但也可以理解:一方面要使运算符的使用方法与其原来一致,另一方面扩展其功能只能通过函数的方式(c++中,“功能”都是由函数实现的)。

为什么使用操作符重载?

对于系统的所有操作符,一般情况下,只支持基本数据类型和标准库中提供的class,对于用户自己定义的class,如果想支持基本操作,比如比较大小,判断是否相等,则需要用户自己来定义关于这个操作符的具体实现。比如,这个预算符,我想用某一个字段进行比价判断是否相等,这就需要程序员重新赋予这个运算符的具体操作了。


重载()运算符

class Distance
{
   //私有成员
   private:
      int feet;
      int inches;
      char dis[10];
   public:
      // 所需的构造函数
      Distance(){
         feet = 0;
         inches = 0;
      }
      Distance(int f, int i){
         feet = f;
         inches = i;
      }
      // 这是创建一个可以传递任意数目参数的运算符函数。
      /**
       * 重载了括号(),
       * 传入4个参数,分别进行初始化,最后将新的对象返回出去
       */
      Distance operator ()(int a, int b, int c, char d[10])
      {
         Distance D;
         // 进行随机计算
         D.feet = a + c + 10;
         D.inches = b + c + 100 ;
         strcpy(D.dis, d);
         //返回新的Distance对象
         return D;
      }
      //打印距离的方法
      void displayDistance()
      {
         cout << "feet: " << feet <<  " inches:" <<  inches << ", dis:" << dis << endl;
      }
};

在上面的代码中,我们看到**distance operator () (int a, int b, int c, char d[10])**方法,这里是重载了"()"操作符,需要传入4个参数,重新定义一个distance类,并且利用传入的参数初始化此类的成员变量,最后返回出去。当然,这里必须要用一个distance类变量才能够调用此方法,然后利用一个新的变量来接收返回值。

具体的测试代码如下所示:

void kuohaoTest(){
   Distance D1(111, 130), D2;

   cout << "first distance : "; 
   D1.displayDistance();

   //调用distance变量的()方法,需要对应参数的个数
   D2 = D1(10, 10, 10, "765");
   cout << "second distance :"; 
   D2.displayDistance();
}

运行结果如下图所示:
运行结果

重载 []

const int SIZE = 10;
class safearray
{
   private:
      int arr[SIZE];
   public:
      safearray() 
      {
         register int i;
         for(i = 0; i < SIZE; i++)
         {
           arr[i] = i;
         }
      }
      
      int & operator[](int i)
      {
          if( i > SIZE )
          {
              //当传入的index大于数组的长度,则返回第一个元素
              return arr[0];
          }
          return arr[i];
      }
};

在上面中,重载了[],里面做了一个判断,如果传入的i超过了数组的长度,那么就返回数组的第一个数据,保证了访问数组时,不会出现数组越界的情况。

下面是测试代码

/**
 * 重载方括号,保证数组不会越界
 */
void fangkuohaoTest(){
   safearray A;
   cout << "A[2] 的值为 : " << A[2] <<endl;
   cout << "A[5] 的值为 : " << A[5]<<endl;
   cout << "A[12] 的值为 : " << A[12]<<endl;
}

在第三个里面,我们需要访问数组的第13个数据,第13个数据显然是不存在的,因为总共只有10个数据。因为判断到超过了数组的长度,所以返回来的必然是第一个数据。

运行结果如下图所示:
运算结果

重载++ / ->

class obj {
   static int i, j;
public:
   void f() const { cout << "f: " << i++ << endl; }
   void g() const { cout << "g: " << j++ << endl; }
};

// 静态成员定义
int obj::i = 1;
int obj::j = 12;

// 为上面的类实现一个容器
class objContainer 
{
   vector<obj*> a;
public:
   void add(obj* obj)
   { 
      a.push_back(obj);  //调用向量的标准方法
   }
   
   friend class smartPointer;
};

// 实现智能指针,用于访问类 Obj 的成员
class smartPointer {
   objContainer oc;
   int index;
public:
   smartPointer(objContainer &objc)
   { 
       oc = objc;
       index = 0;
   }
   // 返回值表示列表结束
   bool operator ++ () // 前增量,只有一个括号
   { 
     if(index >= oc.a.size()) return false;
     if(oc.a[++index] == 0) return false;//index加1
     return true;
   }
   
   bool operator ++ (int) // 后增量,括号里面有一个int类型
   { 
      return operator++();
   }
   
   // 重载运算符 ->
   obj* operator -> () const 
   {
     if(!oc.a[index])
     {
        cout << "Zero value";
        return (obj*)0;
     }
     //不为空,指向oc.a向量里面的obj类的实例
     return oc.a[index];
   }
   
};

void pointerTest(){
   const int sz = 10;
   obj o[sz];
   objContainer oc;
   for(int i = 0; i < sz; i++)
   {
       oc.add(&o[i]);
   }
   smartPointer sp(oc); // 创建一个迭代器
   
   do {
      sp->f(); // 智能指针调用
      sp->g();
   } while(sp++);
}

在上面的smartPointer类,重写了++和->两个方法,都是做了防止越界的判断。在pointerTest()方法里面,objContainer变量中先放入了10个obj变量,然后依次调出来,打印语句。结果如下图所示:
运算结果

总结

上面注意说明了利用operator关键字进行一些操作符的重新定义,使之更加满足自己业务的需要。

只有C++预定义的操作符集中的操作符才可以被重载,例如+,-,*,/,%,^…等等,但是都不改变它们之间的操作个数和优先级;以及一些内置类型的操作符不能改变,比如int类型的+。

以上就是所有内容,如有任何问题,请及时与我联系,谢谢。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页