基础备忘:特殊运算符重载

1.“++”和“--”重载

“++”和“--”运算符的重载要区分前置和后置两种形式。例如,表达式"++a"和"a++"是不一样的。

如果不区分前置和抹黑,则使用operator++()或operator--()即可,否则要使用operator++()或operator--()来重载前置运算符,operator++(int)和operator--(int)来重载后置运算符,调用时,参数int被传递值0。例如:

#include<iostream>
using namespace std;
class A
{
      private:
              int n;
      public:
             A(int x=0)
             {
                   n=x;
                   }
             int getn()
             {
                 return n;
                 }
             A operator++();
             A operator++(int);
             A operator--();
             A operator--(int);
      };
A A:: operator++()
{
      ++n;
      return *this;
      }
A A:: operator++(int )
{
      n++;
      return *this;
      }
A A::operator--()
{
     --n;
     return *this;
                    }
A A::operator--(int)
{
     n--;
     return *this;
                    }
int main()
{
    A ob(3);
    cout<<"ob.n = "<<ob.getn()<<endl;
    ++ob;
    cout<<"ob.n = "<<ob.getn()<<endl;
    ob++;
    cout<<"ob.n = "<<ob.getn()<<endl;
    --ob;
    cout<<"ob.n = "<<ob.getn()<<endl;
    ob--;
    cout<<"ob.n = "<<ob.getn()<<endl;
    ob.operator--(0);//等价于ob--; 
    cout<<"ob.n = "<<ob.getn()<<endl;
    system("pause");
    
    }

声明和定义后置的"++"或"--"等运算符重载,必须含有形式参数,在调用时一般为指定实参0。

2.赋值运算符"="重载

事实上,对于任何一个类,如果没有用户自定义的赋值运算符函数,系统会自动地为其生成一个默认的赋值运算符函数,以完成数据成员之间的复制。如:

X & X::operator = (const X &source)

{

    //类对象成员之间的赋值语句

}

一旦类X的两个对象ob1和ob2已创建,就可用ob1=ob2进行赋值了。通常情况下,默认的赋值运算符函数就可以完成赋值任务,但在某些特殊情况下,例如,类中有一种指针类的形式,如果使用默认的运算符函数就会产生指针悬挂的错误。此时,就必须显式地定义一个赋值运算符重载函数,使参数赋值的两个对象有各自的存储空间,以解决这个问题。如:

#include<iostream>
#include<string>
using namespace std;
class Internet
{
      public:
              char *name;
              char *url;
      public:
             Internet(char *name,char *url)
             {
                           Internet::name= new char[strlen(name)+1];
                           Internet::url= new char[strlen(url)+1];
                           if(name)
                           {
                                   strcpy(Internet::name,name);
                                   }
                                   if(url)
                                   {
                                          strcpy(Internet::url,url);
                                          }
                           }
             Internet(Internet &temp)
             {
                               Internet::name=new char[strlen(temp.name)+1];
                               Internet::url=new char[strlen(temp.url)+1];
                               if(name)
                               {
                                       strcpy(Internet::name,temp.name);
                                       }
                               if(url)
                               {
                                      strcpy(Internet::url,temp.url);
                                      } 
                               }
             ~Internet()
             {
                        delete []name;
                        delete []url; 
                        }
             Internet& operator=(Internet &temp)
             {
                       delete[] this->name;
                       delete[] this->url;
                       this->name = new char[strlen(temp.name)+1];
                       this->url= new char[strlen(temp.url)+1];
                       if(this->name)
                       {
                           strcpy(this->name,temp.name);
                       }
                       if(this->url)
                       {
                           strcpy(this->url,temp.url);
                       }
                 return *this;
                  }

      };
int main()
{
    Internet a("pxc","www.csdn.net");
    Internet b=a;//b对象不存在,调用拷贝构造函数
    cout<<b.name<<endl<<b.url<<endl;
    Internet c("Mit","www.mit.edu.cn");
    b=c;//b对象已经存在,调用赋值运算符重载函数 
    cout<<b.name<<endl<<b.url<<endl;
    system("pause"); 
    } 
   

结果:

pxc

www.csdn.net

Mit

www.mit.edu.cn

过程中出现问题:在dev c++中程序死掉,不知为何。后发现是我name错写成了neme。尴尬。

在上述代码中,在类对象还存在的情况下,同仁过程通过拷贝构造函数进行构造,如Internet b=a; 当对象已经存在,同仁过程就通过赋值运算符重载函数进行,如b=c;。

在进行赋值运算符“=”重载时,要注意赋值运算符只能重载为运算符成员函数,不能重载为友元运算符函数,而且赋值运算符重载后不能被继承。

3.下标运算符"[]"重载

下标运算符 operator[]通常用来访问数组中的某个元素,可以看做是一个双目运算符,每一个运算符是中,第二个运算符是数组下标。在类的对象中,可以重载下票运算符,用它来定义相应对象的下标运算。一般来说,下标运算符定义的形式如下:

T1 T:: operator[] (T2);

其中,T是定义下标运算符的类;T2表示下标,其可以是任意类型,如整形、字符型或某个类;T1是数组运算的结果,可以是任意类型,但为了能对数组赋值,一般将其声明为引用开式。在实际的程序中,可以通过下面两种方式来调用下标运算符(x为数组名或对象,y为下标)。

x[y]或x.operator[y]

例:

#include<iostream>
using namespace std;

class IntArray
{
      int *a;
      int sz;
      public:
             IntArray(int size)
             {
                          sz=size;
                          a=new int[size];
                          }
             int &operator[](int i)
             {
                 if(i<0||i>=sz)
                 {
                               cout<<"error"<<endl;
                               exit(1);//越界异常,退出程序 
                               }
                 return a[i];
                 }
             ~ IntArray()
             {
                         delete[]a;//清除地址 
                         }
      };
      
int main()
{
    IntArray a(5);//创建对象 
    a[3]=0;//赋值,不越界 
    cout<<"a[3]= "<<a[3]<<endl;
    a.operator[](3)=0;//赋值,不越界 
    cout<<"a.operator[](3)= "<<a.operator[](3)<<endl;
    cout<<"a[6]= ";
    a.operator[](6)=6;//赋值,越界 
    system("pause");
    return 0;
    } 

在上述代码中,实现了下标运算符"[]"重载,其增加了甉数组下标是否越界的判断功能,下标越界返回"error",否则返回正常的数组元素值。在主函数mian中,分别用了两种方式调用下标运算符。此外,c++不允许把下标运算符函数作为外部函数来定义,只能是非静态的成员函数。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值