⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 overloadingoperators.cpp

📁 这我们老师对是面向对象程序设计(清华大学出版社)一书制作的PPT
💻 CPP
字号:

#include<iostream.h>
#include<string.h>
#include<stdlib.h>

//【例13.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';
}



//【例13.2】 用友元函数实现例13.1中的运算符重载。

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


//【例13.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<<" "<<z<<"\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();
}



//【例13.4】定义一个复数类CComplex,在CComplex中包含两个数据成员,
     //即复数的实数部分real和复数的虚数部分imag。用友元函数对该类的加、减、乘、除四个运算符进行重载。

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();		//输出相除结果
}


//【例13.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();
}


//【例13.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();
}



//【例13.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';	
}


//【例13.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';
}



//【例13.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';
}


//【例13.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
}



//【例13.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 main13_11(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;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -