zoukankan      html  css  js  c++  java
  • 运算符重载

    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;
    }
    
     
    

  • 相关阅读:
    OleDbCommand 的用法
    递归求阶乘
    C#重写窗体的方法
    HDU 5229 ZCC loves strings 博弈
    HDU 5228 ZCC loves straight flush 暴力
    POJ 1330 Nearest Common Ancestors LCA
    HDU 5234 Happy birthday 01背包
    HDU 5233 Gunner II 离散化
    fast-IO
    HDU 5265 pog loves szh II 二分
  • 原文地址:https://www.cnblogs.com/flysnail/p/2055283.html
Copyright © 2011-2022 走看看