运算符重载

在研究类的默认成员函数的时候我们接触到了运算符重载,其中包括赋值操作符重载 取地址操作符重载 const 修饰的取地址操作符的重载
这一节我们主要来研究一下赋值运算符以及·加加减减的重载
运算符的重载实际上是对运算符函数的重载来实现的
话不多说直接上代码来看

#define _CRT_SECURE_NO_WARNINGS 

#include<iostream>
using namespace std;

class complex
{
private:
	double real;
	double imag;
public:
	complex(double r = 0.0, double i = 0.0)
	{
		real = r;
		imag = i;
	}
	void display();
	complex operator +(const complex &c);//二元加重载成员函数
	complex operator -(const complex &c);//二元减重载成员函数
	complex operator - ();//一元重载成员函数
};

void complex::display()
{
	cout << "real = " << real << endl;
	cout << "imag = " << imag << endl;
}
complex complex::operator+(const complex &c)
{
	double r = real + c.real;
	double i = imag + c.imag;
	return complex(r, i);
}

complex complex::operator-(const complex &c)
{
	double r = real- c.real;
	double i = imag - c.imag;
	return complex(r, i);
}
complex complex::operator-()
{
	return complex(-real, -imag);
}
int main()
{
	complex a(1.5,52.2), b(2.3,63.2);
	complex c = a + b;
	complex d = -a;
	d   .display();
	c.display();
	system("pause");
	return 0;
}

通过这段代码我们发现,通过对于运算符的重载可以实现对于类的想要操作,语法通过代码也就很明显的展现出来

函数类型 + operator + 重载的运算符(形参列表)
{
函数体;
}
重载类的成员函数的时候,参数个数 = 原操作数个数 -1(后置++,前置++除外);
当类的对象调用这种运算符函数的时候,对象中的成员数据就是一个操作数,另一个操作数通过参数传递来获得。
看完这 很多人应该想问为啥参数个数等于原来操作数减1?
this指针不知道你是否还记得?
当操作数为双目运算符的时候,其中一个运算数据是对象本身的数据,由this指针给出,另一个操作数的数据需要传参数来确定,(当然,特殊情况狂特殊考虑),运算符是单目运算符的时候,操作数直接由this指针给出,就不需要任何函数来传递。

类的友元函数的重载
运算符重载为类的友元函数时,所需要的操作数必须通过函数形参来传递。

上面我们刚提到了this指针,在学习友元的时候我们说友元函数没有this指针,所以参数传递就只有是形参来传递了。
也分为两种情况:

  1. 当运算符为双目运算符时,以加号为例 a+b 实际上就是 operator+(a,b);
  2. 当运算符为单目运算符的时候 比如后置减减,实际上就是调用函数operator–(a);
    具体怎么样直接上代码看实际情况中的操作
class complex
{
private:
	double real;
	double imag;
public:
	complex(double r = 0.0, double i = 0.0)
	{
		real = r;
		imag = i;
	}
	void display();
	friend complex operator-(const complex &c1, const complex &c2);//二元重载减友元函数
	friend complex operator-(const complex &c);//一元重载减友元函数
	friend complex operator+(const complex &c1, const complex &c2);//二元重载加友元函数
};

void complex::display()
{
	cout << "real = " << real << endl;
	cout << "imag = " << imag << endl;
}

complex operator-(const complex &c1, const complex &c2)
{
	double r = c1.real - c2.real;
	double i = c1.imag - c2.imag;
	return complex(r, i);
}
complex operator-(const complex &c)
{
	double r = -c.imag;
	double i = -c.real;
	return complex(r,i);  
}
complex operator+(const complex &c1, const complex &c2)
{
	double r = c1.real + c2.real;
	double i = c1.imag + c2.imag;
	return complex(r, i);
}

int main()
{
	complex a(1.5, 52.2), b(2.3, 63.2);
	complex c = a + b;
	complex d = -a;
	d.display();
	c.display();
	system("pause");
	return 0;            
}

我们可以发现,在友元函数重载的过程中,函数参数 = 原来操作数的个数,至少有一个自定义类型的形式参数,在调用这种运算符函数的时候,所有的操作数都要通过参数传递来获得。

友元函数不能重载的运算符
= ()-> 。

接下来就是我们学习C++过程中经常需要实现的多种运算符的重载:

一·. ++和–的重载
主要还是强调一下后置++ --的重载操作,前置操作在前面实现复数运算的时候已经实现,主要是后置时候的操作,我们需要增加一个int类型的参数,在调用时,参数Int并不参与运算,只是用来区分重载函数。
话不多说,直接上代码:


class test
{
private:
	int t1, t2;
public:
	test(int num1, int num2);
	test operator++();//后置加加
	test operator--();//后置减减
	test operator++(int);//前置加加
	test operator--(int);//前置减减
	void display();
};

test::test(int num1, int num2)
{
	t1 = num1;
	t2 = num2;
}
test test::operator++()
{
	++t1;
	++t2;
	return *this;
}

test test::operator--()
{
	--t1;
	--t2;
	return *this;
}
void test::display()
{
	cout << "t1 = " << t1 << endl;
	cout << "t2 = " << t2 << endl;
}
test test::operator++(int)
{
	int temp1 = t1;
	int temp2 = t2;
	t1++;
	t2++;
	return test(temp1,temp2);
}
test test::operator--(int)
{
	int temp1 = t1;
	int temp2 = t2;
	t1--;
	t2--;
	return test(temp1, temp2);
}

再来看常用的 = 的重载

相信大家在看完加加减减的重载后对于=一定也有自己的想法吧,这个主要是但是我们需要注意几点:

  1. 有一个引用参数,为了防止对赋值号右边进行拷贝,从而提高函数运行时效率,
  2. 函数返回了引用而不是对象,这样,赋值构造函数不如使用引用参数和返回引用更加有效。
    例如:

class String
{
private:
	char* ptr;
public:
	String( char* s)
	{
		ptr = new char[strlen(s) + 1];
		strcpy(ptr, s);
	}
	~String()
	{
		delete ptr;
	}
	void print()
	{
		cout << ptr << endl;
	}
	String &operator =  ( String & s);//函数返回引用更为有效
};

String &String::operator=(String &s )
{
	if (this == &s)
	{
		return *this;
	}
	else {
		delete ptr;
		ptr = new char[strlen(s.ptr) + 1];
		strcpy(ptr, s.ptr);
		return *this;
	}
}

int main()
{
	char* str = (char*)"你好";
	String p1(str);
	char* str1 =(char*) "我美吗";
	String p2(str1);
	p1 = p2;
	p1.print();
	system("pause");
	return 0;
}

这样就完成了赋值运算符的重载,其实根据类私有成员的不同,重载的方式是不同的,具体还要看怎么实现,掌握语法和原理很重要,在接下来的学习中一起看啊。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值