`
java-mans
  • 浏览: 11415975 次
文章分类
社区版块
存档分类
最新评论

C++学习之操作符重载

阅读更多

C++之操作符

具有函数重载特征

对于整数进行加、减、乘、除等各种操作,其操作形式并不是函数形式(add(a, b)),而是操作符a+b形式,

由此可知,C++其实把操作符也看成是与函数有同样性质的实体。

因此,可以对操作符进行函数那样的定义,之后就可以自由的使用该操作符了,

如下是一个对一个二维坐标系上的实数矢量Point类,设计矢量类的加法代码实现:

#include <iostream>
using namespace std;

class Point
{
	int x, y;
public:
	void set(int a, int b)
	{
		x = a;
		y = b;
	}

	void print()const
	{
		cout << "(" << x << "," << y << ")" << endl;
	}

	friend Point operator+(const Point& a, const Point& b);
	friend Point add(const Point& a, const Point& b);
};

Point operator+(const Point& a, const Point& b)
{
	Point s;
	s.set(a.x + b.x, a.y + b.y);
	return s;
}

Point add(const Point& a, const Point& b)
{
	Point s;
	s.set(a.x + b.x, a.y + b.y);

	return s;
}

int main()
{
	Point a, b;
	a.set(3, 2);
	b.set(1, 5);
	(a + b).print();
	operator+(a, b).print();
	add(a, b).print();

	return 0;
}


代码中(a+b)的操作,实际上C++是调用了函数operator+(a, b),C++将a+b转译为对operator+(a+b)的调用。

如果不用操作符,a+b的功能也是可以实现的。那就是要调用add函数,从上述代码可以看出,add函数与+操作符的功能完全一致。因此,操作符并不是必需的。

在C++中,内部已经实现了多几个版本的+操作,例如整数+,浮点+等。因此,任何自定义的+操作符行为都是对C++原有+操作符的重载。同理,其他操作符的定义也是重载。

同时从上面的代码可以看出,operator+和add函数体重都要用Point对象进行私有数据访问,但是作为普通函数不能访问类的私有成员,因此在Point类中以friend关键字引导进行函数声明后,就可以访问类的私有数据了。

C++操作符的一些规定:

1)不能创建一些新的操作符,例如@, **等不能定义他们为C++操作符。

2)C++还规定双目操作符“::”,“.”,“.*”不能重载,同时三目操作符“? :”不能重载。

3)C++的操作符重载后,其优先级和结合性是不会改变的。

4)操作数个数不变。

5)操作符的重载只能针对自定义的类型。即在操作符定义的参数表中,至少有一个参数必须是自定义类型。

另外,操作符可以作为类中的成员,也就是类的成员函数,这样,就不需要用friend了,可以直接访问类中的成员了。对上述的程序进行了修改,将operator+作为类成员函数,重载操作<<代替print操作。以使Point对象可以直接进行流操作:

代码如下:

#include <iostream>
using namespace std;

class Point
{
	int x, y;
public:
	void set(int a, int b)
	{
		x = a;
		y = b;
	}
	Point operator+(const Point& d)
	{
		Point s;
		s.set(x + d.x, y + d.y);
		return s;
	}
	friend ostream& operator<<(ostream& o, const Point& d);
};

inline ostream& operator<<(ostream& o, const Point& d)
{
	return o << "(" << d.x << ", " << d.y <<")\n";
}

int main()
{
	Point p1, p2;
	p1.set(3, 5);
	p2.set(3, 2);
	cout << p1 + p2;

	return 0;
}


从上述代码可以看出,成员操作符定义中只有一个参数,与普通操作符不同。因为成员函数总是与对象捆绑使用,被捆绑的对象就是被操作的第一参数,因此,单目成员操作符没有参数,双目成员操作符只有一个参数。因此代码中+操作符只有一个参数。

所以s+t的操作可以写成成员函数的调用方式,即s.operator + (t)。

此处<<操作的前置对象是流类型的cout,不是Point类型,所以不能把该<<操作设计成Point的成员,而只能设计成普通函数,因而,其参数表中就有两个参数,而且为了能访问Point私有数据,必须用关键字friend引导。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics