c++//运算符重载//20191201

重载运算符的规则

不允许用户定义新的运算符,只能对c++已有的运算符进行重载
C++允许重载的运算符见表10.1(P313),不能重载的运算符有5个,见下页的表
重载不能改变运算符运算对象(操作数)的个数
重载不能改变运算符的优先级、结合性
重载运算符的函数不能有默认的参数
……(见书P313-314)
C++中不允许重载的运算符
在这里插入图片描述

运算符重载函数作为类成员函数

重载运算符的函数一般形式:
函数类型 operator 运算符名称(形参表)
{
函数体(对运算符的重载处理)
}

#include<iostream>//运算符重载的函数作为类的成员函数
using namespace std;
class Complex
{
public:
	Complex() { real = 0; imag = 0; }//<此行可省略>??
	Complex(double r, double i) { real = r; imag = i; }
	Complex operator+(Complex& c33)
	{
		Complex c;
		c.real = real + c33.real;
		c.imag = imag + c33.imag;
		return c;
	}
	void display()
	{
		cout << "(" << real << "," << imag << "i)" << endl;
	}
private:
	double real;
	double imag;
};
int main()
{
	Complex  c1(0,0), c2(5, -10), c3;
	c3 = c1.operator+(c2);//c3=c1+c2
	cout << "c1 = "; c1.display();
	cout << "c2 = "; c2.display();
	cout << "c3 = "; c3.display();
}

void  AddA(Complex &c1, Complex &c2 )//一般函数
   { 
	real=c1.real+c2.real;   
	imag=c1.imag+c2.imag; 
}
函数调用:
	a3.AddA(a1,a2);(相当于:a3=a1.operator+(a2);
#include<iostream>
using namespace std;
class Room
{
private:double  
	Length, Wide;
public:  
	Room(double a = 0.0, double b = 0.0){Length = a;Wide = b;}
	  void Show(void)
	  {
		  cout << "Length=" << Length << '\t' << "Wide=" << Wide << endl;
	  }
	  Room operator+(Room&);//重载运算符+,函数原型
};
Room Room::operator + (Room& r)   //重载运算符,函数定义
{
	Room rr;
	rr.Length = Length + r.Length;
	rr.Wide = Wide + r.Wide;
	return rr;
}
void main(void) {
	Room r1(3, 2), r2(1, 4), r3;
	r1.Show(); r2.Show();
	r3 = r1 + r2;   r3.Show();
}

#include<iostream>
using namespace std;
class Complex
{
private:double  real, imag;
public:
	Complex() { real = 0; imag = 0; }
	Complex(double r, double i) { real = r; imag = i; }
	void operator ==(const Complex& x) const
	{
		if ((real == x.real) && (imag == x.imag))
			cout << "(" << real << "+" << imag << "i)" << "相等" << "(" << x.real << "+" << x.imag << "i)" << endl;
		else
			cout << "(" << real << "+" << imag << "i)" << "不相等" << "(" << x.real << "+" << x.imag << "i)" << endl;
	}
};
int main(void) {
	cout << "请输入第1个复数:";
	int a1, b1;
	cin >> a1 >> b1;
	cout << "请输入第2个复数:";
	int a2, b2;
	cin >> a2 >> b2;
	Complex c1(a1, b1), c2(a2, b2);
	c1 == c2;
	return 0;
}


运算符重载函数作为友元函数

<类型> <运算符>(形参1,形参2)
{ 函数体 }
说明:形参1与形参2通常为两个参加运算的对象引用。
例如:A a ,b , c;
c=a+b; 实际上是 c=operator+(a, b);
c=++a; 实际上是 c=operator++(a);
c+=a; 实际上是 operator+=( c, a );
说明:参加运算的操作数均作为函数的参数(红色字体表示)

#include<iostream>
using namespace std;
class Complex
{
private:	double  real, imag;
public:
	Complex() { real = 0; imag = 0; }
	Complex(double r, double i) { real = r; imag = i; }
	friend void operator==(Complex& x1, Complex& x2)
	{
		if ((x1.real == x2.real) && (x1.imag == x2.imag))
			cout << "(" << x1.real << "+" << x1.imag << "i)" << "相等" << "(" << x2.real << "+" << x2.imag << "i)" << endl;
		else
			cout << "(" << x1.real << "+" << x1.imag << "i)" << "不相等" << "(" << x2.real << "+" << x2.imag << "i)" << endl;
	}
};
int main(void) {
	cout << "请输入第1个复数:";
	int a1, b1;
	cin >> a1 >> b1;
	cout << "请输入第2个复数:";
	int a2, b2;
	cin >> a2 >> b2;
	Complex c1(a1, b1), c2(a2, b2);
	c1 == c2;
	return 0;
}

重载双目运算符

双目运算重载为友元函数的定义格式
friend <返回值类型> operator #(<类型1> <参数1>, <类型2> <参数2>)
{ …… }
使用格式为:
<类型1> a;
<类型2> b;
a # b 或 operator#(a,b)

#include <iostream>
#include <string.h>
using namespace std;
class String
{
public:
	String() { p = NULL; }
	String(char* str);
	friend bool operator>(String& string1, String& string2);
	friend bool operator<(String& string1, String& string2);
	friend bool operator==(String& string1, String& string2);
	void display();
private:
	char* p;
};
String::String(char* str)
{
	p = str;
}
void String::display()
{
	cout << p;
}
bool operator>(String& string1, String& string2)
{
	if (strcmp(string1.p, string2.p) > 0)
		return true;
	else   return false;
}
bool operator<(String& string1, String& string2)
{
	if (strcmp(string1.p, string2.p) < 0)
		return true;
	else     return false;
}
bool operator==(String& string1, String& string2)
{
	if (strcmp(string1.p, string2.p) == 0)
		return true;
	else    return false;
}
int main()
{
	String string1("Hello"), string2("Book"), string3("Computer");//vs2019不可行,待后续回归
	cout << (string1 > string2) << endl;
	cout << (string1 < string3) << endl;
	cout << (string1 == string2) << endl;
	return 0;
}

重载单目运算符

单目运算是指:只有一个操作数的运算,所以也称一元运算。如, !a , ++i ,j- - 等等。
单目运算符既可以重载为成员函数,也可以重载为类的友元函数。
单目运算符重载为成员函数的定义格式:
class <类名>
{ …
<返回值类型> operator # (); //运算符重载为成员函数
};
<返回值类型> <类名>::operator # () { … } //重载为成员函数的定义
使用格式:
<类名> a;
#a 或,a.operator#()//重载函数的调用
单目运算符重载为友元函数的定义格式:
定义格式
<返回值类型> operator #(<类型> <参数>) //运算符重载为友元函数的定义
{ …… }
使用格式为:
<类型> a;
#a 或 operator#(a) //重载函数的调用

典型单目运算符为“++” 或(- -)
它们分别有前置与后置两种
如果没有特殊说明
它们的前置用法与后置用法均使用同一个重载函数:
operator ++()
为了能够区分++- -)的前置与后置用法
可为它们再写一个重载函数用于实现它们的后置用法
该重载函数应有一个形式上的int型参数:
 operator ++(int);++运算为例,重载函数定义:
“++”为前置运算符,定义格式:
<类型><类名>::operator ++() { 函数体 }++”为后置运算符,定义格式:
<类型><类名>::operator ++(int) { 函数体 }
重载函数的调用格式:
前置“++”运算符,调用格式:
<操作对象>.operator ++();
后置“++”运算符,调用格式:
<操作对象>.operator ++(1)
#include <iostream>
using namespace std;
class Time
{
public:
	Time() { minute = 0; sec = 0; }//默认构造函数
	Time(int m, int s) { minute = m; sec = s; }//构造函数重载
	Time operator++(); //声明运算符重载成员函数
	void display()//定义输出时间函数
	{
		cout << minute << ":" << sec << endl;
	}
private:
	int minute;
	int sec;
};
Time Time::operator++()
{
	if (++sec >= 60)
	{
		sec = sec - 60;
		++minute;
	}
	return *this;//返回自加后的当前对象
}
int main()
{
	Time time1(34, 0);
	for (int i = 0; i < 61; i++)
	{
		system("cls"); //清屏
		++time1;  time1.display();
	}//如果改变显示方式为类似秒表方式    

	/*for (int i = 0; i < 61; i++)
	{
		++time1;  time1.display();
	}*/
	return 0;
}

总结

对二元运算符,重载为成员函数时,仅一个参数,另一个被隐含;重载为友元函数时,有两个参数,没有隐含参数。
一般来说,一元运算符最好被重载为成员函数,对二元运算符最好被重载为友元函数。

练习

1.假定要对类 AB 定义减号操作符重载成员函数,实现两个 AB 类对象的减法,并返回相减结果,则该成员函数的声明语句为( )
A) AB operator-(AB &a ,AB &b);
B) AB operator-(AB &a ); ✔
C) operator-(AB a );
D) AB & operator-( );
2. 有如下的运算符重载函数定义:
double operator + (int i , int k) { return double (i+k); }
但定义有错误,对这个错误最准确的描述是?
A)+只能作为成员函数重载,而这里的+是作为非成员函数重载的
B)两个int型参数的和也应该是int型,而这里将+的返回值类型声明为double
C)没有将运算符重载函数声明为某个类的友元
D)C++已经提供了求两个int型数据之和的运算符+,不能再定义同样的运算符✔
3. 通过运算符重载,可以改变运算符原有的()
A)操作数类型✔
B)操作数个数
C)优先级
D)结合性
4. 在重载运算符时,其参数表中没有任何参数,这表明该运算符是()
A)作为友元函数重载的单目运算符
B)作为成员函数重载的单目运算符✔
C)作为友元函数重载的双目运算符
D)作为成员函数重载的双目运算符

个人实践

001

#include<iostream>
using namespace std;
class add
{public:
	add() { x = 0, y = 0; }
	add(int a, int b) :x(a), y(b) {}
	friend add operator + (add& c1, add& c2)
	{
		add t;
		t.x = c1.x + c2.x;
		t.y = c1.y + c2.y;
		return t;
	}
	void Display()
	{    
		cout << "<"<<x<<","<<y<<">"<<endl;}
private:
	int x,y;
};
int main()
{
	int a, s, d, f;
	cin >> a >> s >> d >> f;
	add x1(a, s), x2(d, f), x3;
	x3 = x1 + x2;
	x1.Display();
	x2.Display();
	x3.Display();
}

在这里插入图片描述

实验二

#include<iostream>
using namespace std;
#define replace(i,x) for(int i=0;i<x;i++)
class Array
{
public:
	Array();
	Array(int* arr);
	Array operator+(Array a);
	void print_();
private:
	int x[10];
};
Array::Array()
{
	replace(i, 3)
		x[i] = 0;
}
Array::Array(int arr[3])
{
	replace(i, 3)
		x[i] = *arr++;
}
Array Array::operator+(Array a)
{
	Array t;
	replace(i, 3)
		t.x[i] = a.x[i] + x[i];
	return t;
}
void Array::print_()
{
	replace(i, 3)
		cout << x[i] << " ";
	cout << endl;
}
int main()
{
	int a1[3], a2[3];
	cout << "请输入两个一维数组(一维数组含三个元素),回车键隔开" << endl;
	replace(i, 3)
		cin >> a1[i];
	replace(i, 3)
		cin>> a2[i];
	Array a(a1);
	Array b(a2);
	Array c = a + b;
	c.print_();

}


发布了38 篇原创文章 · 获赞 2 · 访问量 1193

猜你喜欢

转载自blog.csdn.net/weixin_44811068/article/details/103336624
今日推荐