C++ 运算符重载

运算符重载

运算符重载是针对新类型数据(如用户自定义类型)的实际需要,对原有运算符进行适当的改造

运算符重载的规则

  • C++中已有的运算符除了少数几个之外,全部可以重载。不能重载的运算符有:成员运算符.,指针运算符.*,作用域运算符::sizeof,三目条件运算符 ?:
  • 重载不改变运算符的 优先级 结合律操作数个数
  • 重载运算符不能有二义性
  • 不能创造新的运算符,如其他语言中的求幂运算符 **,我们可以通过重载^运算符来实现
  • 运算符只能显式重载,不存在隐式重载。如:重载赋值运算符和加法运算符后,object2 = object2 + object1;语句成立,但这并不意味着+=运算符会自动重载,因此object2 += object1;语句不成立。
  • 一般来说,运算符重载形式有两种,重载为类的成员函数和重载为类的友元函数。
    • 友元函数没有隐含的参数this指针,所需操作数必须在参数列表里显式声明,很容易实现隐式类型转换。这样,对双目运算符,友元函数有2个参数,对单目运算符,友元函数有一个参数。但有些运算符不能重载为友元函数,它们是:= , () , [] 和 ->
    • 一般说来,单目运算符最好被重载为成员;对双目运算符最好被重载为友元函数,双目运算符重载为友元函数比重载为成员函数更方便。在第一个参数需要隐式类型转换时,使用友元函数重载运算符较好友元函数也常用于运算符左右操作数类型不同的情况。但是,有的双目运算符还是重载为成员函数为好,例如,赋值运算符。因为,它如果被重载为友元函数,将会出现与赋值语义不一致的地方。

运算符重载为类的成员函数的一般语法形式为:

返回值类型 operator运算符(形参表)	//operator是定义运算符重载函数的关键字
{
  函数体;
}

运算符重载为类的友元函数的一般语法形式为:

friend 返回值类型 operator运算符(形参表)
{
  函数体;
}

= 运算符重载 实现字符串拷贝


class StringPlus{ char* p; };
StringPlus& StringPlus::operator=(const StringPlus& s) {
	if (s.p != NULL) {
		if (p != NULL) delete[]p;
		p = new char[strlen(s.p) + 1];
		strcpy_s(p, strlen(s.p) + 1, s.p);
	}
	else if (p != NULL) {
		delete[]p;
		p = NULL;
	}
	return *this;	//重载'='时特有的语句
}
int main() { StringPlus s1(str1), s1 = s2; ... } //重载'='的使用

++ 运算符重载

"++"运算符重载
#include <iostream>
using namespace std;

class Increase {
public:
	Increase() { value = 0; }
	void  display()  const { cout << value << '\n'; };
	friend Increase operator ++ (Increase&); 		// ++前置	
	friend Increase operator ++ (Increase&, int);	// 后置++
private:  unsigned value;
};
Increase operator ++ (Increase& a) {	 			//++n
	a.value++;   return a;
}
Increase operator ++ (Increase& a, int) { 			//n++
	Increase  temp(a);   a.value++;   return  temp;	//n先参与其他运算或调用,再进行自增
}
int main()
{
	Increase   a, b, n;
	for (int i = 0; i < 10; i++)  a = n++;
	cout << "n = ";   n.display();   cout << "a = ";   a.display();
	for (int i = 0; i < 10; i++)  b = ++n;
	cout << "n = ";   n.display();   cout << "b = ";   b.display();
}
程序运行结果:
n = 10
a = 9
n = 20
b = 20

[ ] 运算符重载

#include <iostream>
using namespace std;
class vector {
public:
	vector(int n) { v = new  int[n]; size = n; }
	~vector() { delete[] v; size = 0; }
	int& operator [] (int i) { return  v[i]; }
private:
	int* v;       int size;
};
int main() {
	vector a(5);
	a[2] = 12;
	cout << a[2] << endl;
}

( ) 运算符重载 实现数学函数的抽象

#include <iostream>
using namespace std;

class F {
public:
	double operator() (double x, double y);
};

double F::operator() (double x, double y)
{ return x * x + y * y; }

int main(){
	F f;
	cout << f(5.2, 2.5) << endl;	//形似函数 z=f(x, y)
}

cpp 1 :复数(a+bi)运算

#include <iostream>
using namespace std;

class Complex
{
public:
	Complex(double r = 0, double i = 0) { Real = r;   Image = i; }
	Complex(int a) { Real = a;  Image = 0; }
	void print() const;
	friend Complex operator+ (const Complex& c1, const Complex& c2);
	friend Complex operator- (const Complex& c1, const Complex& c2);
	friend Complex operator- (const Complex& c);
private:
	double  Real, Image;
};
Complex operator + (const Complex& c1, const Complex& c2)
{
	double r = c1.Real + c2.Real;  double i = c1.Image + c2.Image;
	return Complex(r, i);
}
Complex operator - (const Complex& c1, const Complex& c2)
{
	double r = c1.Real - c2.Real;  double i = c1.Image - c2.Image;
	return Complex(r, i);
}
Complex operator- (const Complex& c)	
{
	return Complex(-c.Real, -c.Image);
}
void Complex::print() const
{
	cout << '(' << Real << " , " << Image << ')' << endl;
}

void main()
{
	Complex  c1(2.5, 3.7), c2(4.2, 6.5);
	Complex c;
	c = c1 - c2;	// operator-(c1, c2)
	c.print();
	c = 25 + c2;	// operator+(25, c2)
	c.print();
	c = c2 + 25;	// operator+(c2, 52)
	c.print();
	c = -c1;		// operator-(c1)
	c.print();
}

cpp 2 :矩阵类的运算符重载:

class Matrix{	//矩阵类
int row, col;
int** p;
...
};

//定义一个所有元素全为value的矩阵
Matrix::Matrix(int row, int col, int value)
{
	p = new int*[row];	//分配row个指针
	for (int i = 0; i < row; ++i)
		p[i] = new int[col];	//为每一个指针p[i]分配动态内存,大小为col
	//即分配一个 row * col大小的数组空间用于存放矩阵的元素
	for (int i = 0; i < row; i++)
		for (int j = 0; j < col; j++)
			p[i][j] = value;	//初始化数组所有元素为 value
}

"-"运算符重载实现矩阵减法
Matrix& Matrix::operator-(const Matrix& B)
{
	for (int i = 0; i < row; i++)
		for (int j = 0; j < col; j++)
			p[i][j] -= B.p[i][j];
}

"*"运算符重载实现矩阵乘法
Matrix Matrix::operator*(const Matrix& B) const
{
	Matrix C(row, B.col, 0);	//定义一个所有元素全为 0的矩阵
	//若C=AB,则矩阵C的行数等于矩阵A的行数,C的列数等于B的列数。
	for(int i = 0; i < row; i++)
		for(int j = 0; j < B.col; j++)
			for(int k = 0; k < col; k++)
				C.p[i][j] += (p[i][k] * B.p[k][j]);
	return C;
}

"+="运算符重载实现矩阵加法
Matrix& Matrix::operator+=(const Matrix& B)
{
	for (int i = 0; i < row; i++)
		for (int j = 0; j < col; j++)
			p[i][j] += B.p[i][j];
	return *this;
}

"*="运算符重载实现矩阵乘法
Matrix& Matrix::operator*=(const Matrix& B)
{
	Matrix C(row, B.col, 0);
	for (int i = 0; i < row; i++)
		for (int j = 0; j < B.col; j++)
			for (int k = 0; k < col; k++)
				C.p[i][j] += (p[i][k] * B.p[k][j]);
	*this = C;
	return *this;
}

">>"运算符重载实现矩阵输入
istream& operator>>(istream& is, Matrix& A)
{
	for (int i = 0; i < A.row; i++)
		for (int j = 0; j < A.col; j++)
			is >> A.p[i][j];
	return is;
}

"<<"运算符重载实现矩阵输出
ostream& operator<<(ostream& out, Matrix& A)
{
	for (int i = 0; i < A.row; i++) {
		for (int j = 0; j < A.col; j++) {
			out << A.p[i][j] << " ";	
		}	//用cout << A.p[i][j] << " ";也可,不过不是传统意义上的<<运算符了
		out << endl;
	}
	out << endl;
	return out;
}

int main()
{
	int rowA, colA, rowB, colB;
	cin >> rowA >> colA >> rowB >> colB;
	Matrix A = Matrix(rowA, colA);
	Matrix B(rowB, colB);
	cin >> A >> B;	//输入矩阵A、B的元素
	Matrix C(rowA, colB);	//生成 rowA*colB的矩阵是为了方便存储矩阵加法和乘法的结果
	C = A - B;	cout >> C;
	C = A * B;	cout >> C;
	   A += B;	cout >> A;
	   B *= A;	cout >> B;
}
//由此可见,运算符重载后,矩阵的运算表达式可以非常简洁、明练、易懂

cpp 3 :有理数计算(有缺陷版本)

#include <iostream>
using namespace std;

class Rational
{
public:
	Rational(long n, long d = 1);    // 构造函数,把长整型转换成Rational类型
	friend Rational operator+ (const Rational&, const Rational&);
	friend ostream& operator<< (ostream&, const Rational&);
	operator double(); 	   // 类型转换函数
private:   long  Numerator, Denominator;
};

// 把长整型转换成Rational类型
Rational::Rational(long n, long d) { Numerator = n;  Denominator = d; }
// 把 Rational 类型转换成 double 类型 
Rational :: operator double()
{
	return double(Numerator) / double(Denominator);
}
Rational operator+ (const Rational& r1, const Rational& r2)
{
	long n, d;
	n = r1.Numerator * r2.Denominator + r1.Denominator * r2.Numerator;
	d = r1.Denominator * r2.Denominator;
	return  Rational(n, d);
}
ostream& operator << (ostream& output, const Rational& x)
{
	output << x.Numerator << "/" << x.Denominator;     return output;
}

int main()
{
	Rational  a(2, 4), b = (1, 2), c(0);
	c = a + b;		// 使用友员重载 “+” 和 缺省重载 “=”
	cout << a << " + " << b << " = " << c << endl;	// 以分数形式显示
	// 以实数形式显示,调用类型转换函数:
	cout << double(a) << " + " << double(b) << " = " << double(c) << endl;
	c = b + Rational(1);			// 调用构造函数作类型转换
	cout << b << " + " << 1 << " = " << c << endl;
	cout << double(b) << " + " << 1 << " = " << double(c) << endl;
	return 0;
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值