• 运算符重载


    1、重载单目运算符。

    class CPoint
    {
    	int x,y;
    	public:
    	CPoint(int vx,int vy)
    	{x=vx;y=vy;}
    	CPoint(){x=0;y=0;}
    	void Print();
    	CPoint operator++();  //前置++运算符的声明
    	CPoint operator--();  //前置--运算符的声明
    };
    
    void CPoint::Print()
    {cout<<"("<<x<<","<<y<<")\t";}
    
    CPoint CPoint::operator ++()
    {    //前置++运算符的定义
    	if(x<640) x++;  //A
    	if(y<480) y++;  //B
    	return *this;
    }
    
    CPoint CPoint::operator --()
    {
    	if(x>0) x--;
    	if(y>0) y--;
    	return *this;
    }
    
    void main13_1(void)
    {
    	CPoint p1(10,10),p2(200,200);
    	for(int i=0;i<5;i++)
    		(++p1).Print();   //C
    	cout<<'\n';
    	for(i=0;i<5;i++)
    		(--p2).Print();
    	cout<<'\n';
    }
    

     2、友元函数实现例上例中的运算符重载

    lass CPoint2
    {
    	int x,y;
    public:
    	CPoint2(int vx,int vy)
    	{x=vx;y=vy;}
    	CPoint2(){x=0;y=0;}
    	void Print();
    	friend CPoint2 operator++(CPoint2 &); // 用友元函数重载运算符的声明
    	friend CPoint2 operator--(CPoint2 &);
    };
    
    void CPoint2::Print()
    {
    	cout<<"("<<x<<","<<y<<")\t";
    }
    
    CPoint2 operator ++(CPoint2 &c)   //运算符重载的定义
    {
    	if(c.x<640) c.x++;
    	if(c.y<480) c.y++;
    	return c;
    }
    
    CPoint2 operator --(CPoint2 &c)
    {
    	if(c.x>0) c.x--;
    	if(c.y>0) c.y--;
    	return c;
    }
    
    void main13_2(void)
    {
    	CPoint2 p1(10,10),p2(200,200);
    	for(int i=0;i<5;i++)
    		(++p1).Print();     //重载运算符的使用
    	cout<<'\n';
    	for(i=0;i<5;i++)
    		(--p2).Print();
    	cout<<'\n';
    }
    

    3、双目运算符的重载

    class CThree_d
    {
    	int x,y,z;
    public:
    	CThree_d(int vx,int vy,int vz)  //构造函数
    	{x=vx;y=vy;z=vz;}     
    	CThree_d(){x=0;y=0;z=0;}   //无参数的构造函数
    	CThree_d operator +(CThree_d t);  //重载加号"+"
    	CThree_d operator -(CThree_d t);  //重载减号"-"
    	CThree_d operator =(CThree_d t);  //重载赋值符"="
    	void Print(){cout<<x<<"  "<<y<<"\n";}
    };
    
    CThree_d CThree_d::operator+(CThree_d t) { //定义两个对象的"+"运算
    	CThree_d te;
    	te.x=x+t.x;
    	te.y=y+t.y;
    	te.z=z+t.z;
    	return te;   //返回当前对象与t对象之和
    }
    
    CThree_d CThree_d::operator-(CThree_d t) //定义两个对象的"-"运算
    {
    	CThree_d te;
    	te.x=x-t.x;
    	te.y=y-t.y;
    	te.z=z-t.z;
    	return te;   //返回当前对象与t对象之差
    }
    
    CThree_d CThree_d::operator=(CThree_d t) {   //将对象的值赋值给当前对象
    	x=t.x;
    	y=t.y;
    	z=t.z;
    	return *this;
    }
    
    void main13_3(void)
    {
    	CThree_d t1(10,10,10),t2(20,20,20),t3;
    	t3=t1+t2;  //A t1与t2相加给t3
    	t3.Print();  //显示t3对象的数据成员
    	t3=t2=t1;  //将t1对象多重赋值给t2和t3
    	t1.Print();  //显示t1,t2,t3的数据成员
    	t2.Print();
    	t3.Print();
    }
    

    4、定义一个复数类CComplex,在CComplex中包含两个数据成员,实现复数的加减乘除的重载操作

    class CComplex   //定义复数类
    { 
    	float real,imag;  //复数的实部和虚部
    	public:
    	CComplex(float r,float i){real=r;imag=i;}    //带参数的构造函数
    	CComplex(){real=0;imag=0;}   //不带参数的构造函数
    	void Print();      //复数的输出函数
    	friend CComplex operator+(CComplex a,CComplex b);
    	//用友元函数重载复数相加运算符
    	friend CComplex operator-(CComplex a,CComplex b);
    	//重载复数相减运算符
    	friend CComplex operator*(CComplex a,CComplex b);
    	//重载复数相乘运算符
    	friend CComplex operator/(CComplex a,CComplex b);
    	//重载复数相除运算符
    };
    
    void CComplex::Print()   //定义复数的输出函数
    {
    	cout<<real;
    	if(imag>0)cout<<"+";
    	if(imag!=0)cout<<imag<<"i\n";
    }
    
    CComplex operator +(CComplex a , CComplex b)
    {
    	CComplex temp;
    	temp.real=a.real+b.real;
    	temp.imag=a.imag+b.imag;
    	return temp;
    }
    
    CComplex operator -(CComplex a , CComplex b)
    {
    	CComplex temp;
    	temp.real=a.real-b.real;
    	temp.imag=a.imag-b.imag;
    	return temp;
    }
    
    CComplex operator *(CComplex a , CComplex b)
    {
    	CComplex temp;
    	temp.real=a.real*b.real-a.imag*b.imag;
    	temp.imag=a.real*b.imag+a.imag*b.real;
    	return temp;
    }
    
    CComplex operator /(CComplex a , CComplex b)
    {
    	CComplex temp;
    	float tt;
    	tt=1/(b.real*b.real+b.imag*b.imag);
    	temp.real=(a.real*b.real+a.imag*b.imag)*tt;
    	temp.imag=(b.real*a.imag-b.imag*a.real)*tt;
    	return temp;
    }
    
    void main13_4(void)
    {
    	CComplex c1(2.3,4.6) , c2(3.6,2.8) , c3;  //定义三个复数对象
    	c1.Print();   //输出复数c1和c2
    	c2.Print();
    	c3=c1+c2;  //复数c1,c2相加,结果给c3
    	c3.Print();  //输出相加结果
    	c3=c2-c1;  //复数c2,c1相减,结果给c3
    	c3.Print();  //输出相减结果
    	c3=c2*c1;  //复数c1,c2相乘,结果给c3
    	c3.Print();  //输出相乘结果
    	c3=c1/c2;  //复数c1,c2相除,结果给c3
    	c3.Print();  //输出相除结果
    }
    

    5、用成员函数对自增运算符进行重载

    class CIncrease
    {
    public:
    	CIncrease(int x){Value=x;}
    	CIncrease & operator ++(); //前增量
    	CIncrease operator ++(int); //后增量
    	void Display(){cout<<"the Value is "<<Value<<endl;}
    private:
    	int Value;
    };
    
    CIncrease & CIncrease:: operator ++()
    {
    	Value++;
    	return *this;   //返回的为Value已自加的对象
    }
    
    CIncrease CIncrease::operator ++(int)
    {
    	CIncrease temp=*this;  //创建一个中间对象,并将它初始化为当前对象
    	Value++;
    	return temp;   //返回的为Value未自加的对象
    }
    
    void main13_5(void)
    {
    	CIncrease n(20);
    	n.Display();
    	++n;
    	n.Display();
    	(n++).Display();
    	n.Display();
    }
    

    6、用友元函数对自增运算符进行重载

    class CIncrease6
    {
    public:
    	CIncrease6(int x){Value=x;}
    	friend CIncrease6 & operator ++(CIncrease6 &);  //前增量
    	friend CIncrease6 operator ++(CIncrease6 &,int);  //后增量
    	void Display()
    	{
    		cout<<"the Value is "<<Value<<endl;
    	}
    private:
    	int Value;
    };
    CIncrease6 & operator ++(CIncrease6 &a)
    {
    	a.Value++;
    	return a;
    }
    
    CIncrease6 operator ++(CIncrease6 &a,int)
    {
    	CIncrease6 temp(a);
    	a.Value++;
    	return temp;
    }
    void main13_6(void)
    {
    	CIncrease6 n(20);
    	n.Display();
    	++n;
    	n.Display();
    	(n++).Display();
    	n.Display();
    }
    

    7、利用类的缺省赋值运算符产生的指针悬挂问题。

    class CA
    {
    	char *ps;
    public:
    	CA(){ps=0;}
    	CA(char *s)
    	{
    	ps=new char[strlen(s)+1];
    	strcpy(ps,s);
    	}
    	CA & operator=(CA &b);         //如果没有该函数将会产生指针悬挂问题
    	~CA(){if(ps) delete[]ps;}
    	char *GetS(){return ps;}
    };
    
    ///*
    CA & CA::operator=(CA &b)
    {
    	if(ps) delete[]ps;                
    	if(b.ps) 
    	{
    		ps=new char [strlen(b.ps)+1];    
    		strcpy(ps,b.ps);
    	}
    	else ps=0;
    	return *this;
    }
    //*/
    
    void main13_7(void)
    {
    	CA s1("China!"),s2("Computer!");
    	cout<<"s1="<<s1.GetS()<<'\t';
    	cout<<"s2="<<s2.GetS()<<'\n';
    	s1=s2;                               //A
    	cout<<"s1="<<s1.GetS()<<'\t';
    	cout<<"s2="<<s2.GetS()<<'\n'; 
    }
    

    8、对下标运算符进行重载,使之具有检查下表是否越界的功能。

    class CArray
    {
    	int len;
    	float *arp;
    public:
    	CArray(int n=0);
    	~CArray() {if (arp) delete[]arp;}
    	int GetLen() const {return len;}
    	void SetLen(int l)
    	{
    		if(l>0)
    		{
    			if(arp) delete[]arp;
    			arp=new float[l];
    			memset(arp,0,sizeof(float)*l);   //A
    			len=l;
    		}
    	}
    	float & operator[] (int index);      // 定义重载的下标运算符
    };
    
    CArray::CArray(int n)
    {
    	if(n>0){
    		arp=new float[n];
    		memset(arp,0,sizeof(float)*n); 
    		len=n;
    	}
    	else{
    	len=0;
    	arp=0;
    	}
    }
    
    float & CArray::operator[](int index)   //下表运算符的实现
    { 
    	if(index>=len||index<0) {    //如果参数index超出规定的范围,则输出越界信息
        cout<<"\nError:下标"<<index<<"出界!"<<'\n';
        exit(2);
        }
        return arp[index];   //如果不越界,则返回相应的数据
    }
    
    void main13_8(void)
    {
    	CArray m1(10),m2(3);
    	int i;
    	for(i=0;i<10;i++) m1[i]=i;        //重载数组下标的使用
    	for(i=1;i<11;i++)        //B
    		cout<<m1[i]<<"   ";  //C
    		cout<<'\n';
    	m2[2]=26;
    	cout<<"m2[2]="<<m2[2]<<'\n';
    }
    

    9、通过重载函数调用运算符,实现两维数组下标的合法性的检查。

    const int cor1=4;
    const int cor2=4;
    
    class CArray9{
    	float arr[cor1][cor2];
    public:
    	CArray9()
    	{memset(arr,0,sizeof(float)*cor1*cor2);}
    	~CArray9() {}
    	void operator()(int i,int j,float f);     //声明函数调用运算符重载函数
    	float GetElem(int i,int j);
    };
    
    void CArray9::operator()(int i,int j,float f){    //函数调用运算符重载函数的实现
    	if(i>=0&&i<cor1&&j>=0&&j<cor2)
    		arr[i][j]=f;
    	else {
    		cout<<"下标越界!\n";
    	exit(3);
    	}
    }
    
    float CArray9::GetElem(int i,int j){
    		if(i<0||j<0||i>=cor1||j>=cor2){
    		cout<<"下标越界!\n";
    		exit(3);
    	}
    	return arr[i][j];
    }
    
    void main13_9(void)
    {
    	CArray9 a;
    	int i,j;
    	for(i=0;i<4;i++)
    		for(j=0;j<4;j++)
    		a(i,j,(float)i*j);   //A   使用重载的函数调用运算符
    	for(i=0;i<4;i++) {
    		cout<<'\n';
    	for(j=0;j<4;j++){  //B
    		cout<<"a["<<i<<","<<j<<"]="<<a.GetElem(i,j)<<'\t'; //C
    	if((j+1)%5==0) cout<<'\n';
    	}
    	}
    	cout<<'\n';
    }
    

    10、new和delete运算符的重载

    const maxpoints=512;
    
    static struct block
    {    
    	int x,y;
    	block *next;
    }block1[maxpoints];     //静态结构数组,用来申请内存空间供使用
    
    class CPoint10
    {
    	int x,y;
    	static block *freelist;  //空闲链
    	static int used;   //实际用掉的数组元素个数
    public:
    	CPoint10(int vx=0,int vy=0){x=vx;y=vy;}
    	void *operator new (size_t);  //重载new声明
    	void operator delete (void *ptr); //重载delete声明
    	void Print(){cout<<x<<" "<<y<<"\n";}
    };
    
    void *CPoint10::operator new(size_t size)
    {
    	block *res=freelist;  //将空闲链头给res
    	if(used<maxpoints)  //判断是否元素已用完
    	res=&block1[used++];
    	else if(res!=0)
    	freelist=freelist->next;
    	cout<<"调用重载的new."<<endl;
    	return res;
    }
    
    void CPoint10::operator delete(void *ptr)
    {
         ((block *)ptr)->next=freelist;    //将待释放的内存块插入到链头前
         freelist=(block *)ptr;
         cout<<"调用重载的delete."<<endl;
    }
    
    block *CPoint10::freelist=0;     //将静态数据赋初值,空闲链初始为空
    int CPoint10::used=0;       //所用的数组元素的个数初值为0
    
    void main13_10(void)
    {
    	 CPoint10 *pt=new CPoint10(5,7);
    	 pt->Print();
         delete pt;
         CPoint10 *pt1=::new CPoint10;    //调用预定义的new
         ::delete pt1;            //调用预定义的delete
    }
    

    11、类型转换函数举例

    class CRational
    {
    public:
    	CRational(int d,int n){den=d;num=n;}
    	operator double(); //声明类型转换函数,它将Crational类型型转换为double类型
    private:
    	int den,num;
    };
    
    CRational::operator double()
    {
    	return double(den)/double(num);
    }
    
    void main(void)
    {
    	CRational r(5,8);
    	double d=4.7,e,f;
    	d+=r;         //A  将CRational类型隐式转换为double类型
    	e=CRational(r);    //B  将CRational类型强制转换为double类型
    	f=(CRational)r;    //C  强制转换的另一种形式
    	cout<<d<<'\t'<<e<<'\t'<<f<<endl;
    }
    
     
    

  • 相关阅读:
    P1182 数列分段Section II
    P1119 灾后重建
    P1133 教主的花园
    P1077 摆花
    P2002 消息扩散
    P2341 [HAOI2006]受欢迎的牛(tarjan+缩点)
    luoguP1726 上白泽慧音
    P1053 篝火晚会
    P2296 寻找道路
    P1156 垃圾陷阱
  • 原文地址:https://www.cnblogs.com/flysnail/p/2055283.html
Copyright © 2020-2023  润新知