C++操作符重载

重载操作符是具有特殊函数名的函数,关键字operator后面接需要定义的操作符符号。操作符重载也是一个函数,具有返回值和形参表。它的形参数目与操作符的操作数目相同,函数调用操作符可以接受任意数目的操作数。使用运算符重载可以提高代码的可读性。

返回类型 operate 操作符(参数列表)--不属于任何的类,是全局的函数

可以被重载的操作符


不可以被重载的操作符


注意:

1、不能通过连接其他符号来创建新的操作符:比如operator@;

voidoperator @(){}

2、重载操作符必须有一个类类型或者枚举类型的操作数

intoperator +(const int _iNum1 , const int _iNum2 )// 报错

{

return ( _iNum1 + _iNum2);

}

typedefenum TEST {one ,two ,three };

intoperator+(const int _iNum1 , const TEST _test )

{

return _iNum1;

}

3、用于内置类型的操作符,其含义不能改变,例如:内置的整型+,不能改变其含义

5、不再具备短求职特性重载操作符不能保证操作符的求值顺序,在重载&&和||中,对每个操作数都要进行求值,而且对操作数的求职顺序不能做规定,因此:重载&&、||和逗号操作符不是好的做法--重载后不能改变运算符的操作对象的个数以及其原有的优先级

6、作为类成员的重载函数,其形参看起来比操作数数目少1成员函数的操作符有一个默认的形参this,限定为第一个形参。

CTestoperator+(const CTest test1, const CTest test2)const // 报错

{

return test1;

}

CTestoperator+(const CTest test1)const

{

return test1;

}

7、一般将算术操作符定义为非成员函数,将赋值运算符定义成员函数

8、操作符定义为非类的成员函数时,一般将其定义为类的友元

9、== 和 != 操作符一般要成对重载

10、下标操作符[]:一个非const成员并返回引用,一个是const成员并返回引用

11、解引用操作符*和->操作符,不显示任何参数

13、自增自减操作符前置式++/--必须返回被增量或者减量的引用后缀式操作符必须返回旧值,并且应该是值返回而不是引用返回

14、输入操作符>>和输出操作符<<必须定义为类的友元函数


自增自减操作符的实现


class Date
{
public:
	Date(int year = 1996, int month = 4, int day = 15)
		:_year(year)
		,_month(month)
		,_day(day)
	{}

	Date& operator ++()
	{
		_day += 1;
		return *this;
	}


	Date operator ++(int)
	{
		Date temp(*this);
		_day += 1;
		return temp;
	}

	
	
private:
	int _year;
	int _month;
	int _day;

};


int main()
{
	Date d1(2013,12,15);
	d1++;
	Date d2;
	++d2;
	Date d3(d1);
	d1<<d2<<d3<<endl;

	system("pause");
	return 0;
}


输入,输出操作符的实现:需要使用友元函数

友元函数:友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。

例如:friend   double FunctionName(参数列表 );

classCPoint
{
friendclass CTest;
public:
   CPoint(const double _dX = 0.0f, const double_dY =0.0f): m_dX( _dX), m_dY( _dY)
   {}
   friend double Distance( const CPoint _pt1,const CPoint _pt2);
   //double Distance( const CPoint _pt1, constCPoint _pt2);
private:
   double m_dX;
   double m_dY;
};

注意:

a、友元函数可访问类的私有成员,但不是类的成员函数;

b、友元函数不能用const修饰;

c、友元函数可以在类定义的任何地方声明,不受类访问限定符限制;

d、一个函数可以是多个类的友元函数,但只需在各个类中分别声明;

e、友元函数的调用与普通函数的调用和原理相同;

f、其声明可以放在类的私有部分,也可以放在公有部分,无区别

友元类:友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员(当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一个类的友元类);

classCTest
{
public:
   CTest()
   {
       cout << __FUNCTION__ <<endl;
    }
   void DisplayCPoint( const CPoint _point)const
   {
       cout << "X = " <<_point .m_dX << endl;
       cout << "Y = " <<_point .m_dY << endl;
   }
};

友元的优缺点:

优点:提高了程序运行效率

缺点:破坏了类的封装性和隐藏性

注意:

友元关系不能继承;友元关系是单向的,不具有交换性;

友元关系不能传递;


输入,输出操作符的实现:

class Point 
{ 
private: 
	int x;
public: 
	Point(int x1)
	{    x=x1;}
	friend ostream& operator<<(ostream& cout,const Point& p);//使用友元函数重载<<输出运算符
	friend istream& operator>>(istream& cin,Point& p);//使用友元函数重载>>输出运算符
}; 
ostream& operator<<(ostream& cout,const Point& p)
{
	cout<<p.x<<endl;
	return cout;
}
istream& operator>>(istream& cin,Point& p)
{
	cin>>p.x;
	return cin;
}

//调用: 
void main()
{
	Point a(1); 
	Point b(2); 
	cin>>a>>b; 
	cout<<a<<b<<endl;
}


建议:使用重载操作符,可以令程序更自然、更直观,而滥用操作符重载会使得类难以理解,在实践中很少发生明显的操作符重载滥用。但有些程序员会定义operator+来执行减法操作,当一个重载操作符不明确时,给操作符取一个名字更好,对于很少用的操作,使用命名函数通常比用操作符好,如果不是普通操作,没有必要为简洁而用操作符。


实现一个复数类:

#include <iostream>
using namespace std;



class Complex
{
public:
	Complex(const double _dReal = 2.0f, const double _dImage = 3.0f)
		:_dReal(_dReal)
		,_dImage(_dImage)
	{}

	Complex(const Complex& complex)
	{
		_dReal = complex._dReal;
		_dImage = complex._dImage;
	}

	~Complex()
	{}

	Complex& operator=(const Complex &complex)
	{
		if(this != &complex)
		{
			_dReal = complex._dReal;
			_dImage = complex._dImage;
		}
		return *this;
	}

	Complex operator+(const Complex& complex)
	{
		Complex temp = NULL;
		temp._dReal = _dReal + complex._dReal;
		temp._dImage = _dImage + complex._dImage;
		return temp;
	}

	Complex operator-(const Complex& complex)
	{
		Complex temp = NULL;
		temp._dReal = _dReal - complex._dReal;
		temp._dImage = _dImage - complex._dImage;
		return temp;
	}

	Complex operator*(const Complex& complex)
	{
		Complex temp = NULL;
		temp._dReal = _dReal * complex._dReal;
		temp._dImage = _dImage * complex._dImage;
		return temp;
	}

	Complex operator/(const Complex& complex)
	{
		Complex temp = NULL;
		temp._dReal = _dReal / complex._dReal;
		temp._dImage = _dImage / complex._dImage;
		return temp;
	}

	Complex& operator+=(const Complex& complex)
	{
		_dReal += complex._dReal;
		_dImage += complex._dImage;
		return *this;
	}

	Complex& operator-=(const Complex& complex)
	{
		_dReal -= complex._dReal;
		_dImage -= complex._dImage;
		return *this;
	}

	Complex& operator*=(const Complex& complex)
	{
		_dReal *= complex._dReal;
		_dImage *= complex._dImage;
		return *this;
	}

	Complex& operator/=(const Complex& complex)
	{
		_dReal /= complex._dReal;
		_dImage /= complex._dImage;
		return *this;
	}

	bool operator>(const Complex& complex)
	{
		if(_dReal > complex._dReal)
		{
			return 1;
		}
		else if(_dReal < complex._dReal)
		{
			return 0;
		}
		else if(_dReal == complex._dReal)
		{
			if(_dImage > complex._dImage)
			{
				return 1;
			}
			else 
			{
				return 0;
			}
		}
	}

	bool operator>=(const Complex& complex)
	{
		if(_dReal > complex._dReal)
		{
			return 1;
		}
		else if(_dReal < complex._dReal)
		{
			return 0;
		}
		else if(_dReal == complex._dReal)
		{
			if(_dImage >= complex._dImage)
			{
				return 1;
			}
			else 
			{
				return 0;
			}
		}
	}

	bool operator<(const Complex& complex)
	{
		if(_dReal < complex._dReal)
		{
			return 1;
		}
		else if(_dReal > complex._dReal)
		{
			return 0;
		}
		else if(_dReal == complex._dReal)
		{
			if(_dImage < complex._dImage)
			{
				return 1;
			}
			else 
			{
				return 0;
			}
		}
	}

	bool operator<=(const Complex& complex)
	{
		if(_dReal < complex._dReal)
		{
			return 1;
		}
		else if(_dReal > complex._dReal)
		{
			return 0;
		}
		else if(_dReal == complex._dReal)
		{
			if(_dImage <= complex._dImage)
			{
				return 1;
			}
			else 
			{
				return 0;
			}
		}

	}

	bool operator==(const Complex& complex)
	{
		if(_dReal == complex._dReal && _dImage == complex._dImage)
		{
			return 1;
		}
		else 
		{
			return 0;
		}
	}

	bool operator!=(const Complex& complex)
	{
		if(_dReal == complex._dReal && _dImage == complex._dImage)
		{
			return 0;
		}
		else 
		{
			return 1;
		}
	}

	


private:
	double _dReal;
	double _dImage;
};


int main()
{
	Complex c1(1.0f, 1.0f);
	Complex c2(c1);
	Complex c3(4.0f, 8.0f);
	Complex c4 = c1 + c2;
	Complex c5 = c3 - c1;
	Complex c6 = c3 * c1;
	Complex c7 = c3 / c1;
	Complex c8 = c5;
	Complex c9;
	c9 += c3;
	Complex c10;
	c10 -= c1;
	Complex c11;
	c11 *= c3;
	Complex c12;
	c12 /= c1;
	Complex c13;
	int ret = c2 > c1;//ret=0时小于或等于, ret=1时大于
	int temp = c6 < c1;//temp=0时大于或等于, temp=1时小于
	int ret1 = c1 == c2;//ret1=0时不等于,ret1=1时等于
	int ret2 = c1 >= c2;//ret2=0时小于,ret2=1时大于或者等于
	int ret3 = c1 <= c2;//ret3=0时大于,ret3=1时小于或者等于
	int ret4 = c1 != c3;//ret4=1时不等于,ret4=0时等于
   

	system("pause");
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值