C++学习(五)_运算符重载

重载运算符

首先我们来看重载运算符的定义:

重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。

在C++中支持的重载运算符有:

不支持的重载运算符:


重载运算符的规则

运算符重载为类的成员函数的一般语法形式为:
函数类型 operator 运算符(形参表)
{
函数体;
}
运算符重载为类的友元函数的一般语法形式为:
friend 函数类型 operator 运算符(形参表)
{
函数体;
}
其中,函数类型就是运算结果类型;operator是定义运算符重载函数的关键字;运算符是重载的运算符名称。

当运算符重载为类的成员函数时,函数的参数个数比原来的操作个数要少一个;

当重载为类的友元函数时,参数个数与原操作数个数相同。

原因是重载为类的成员函数时,如果某个对象使用重载了的成员函数,自身的数据可以直接访问,就不需要再放在参数表中进行传递,少了的操作数就是该对象本身。

而重载为友元函数时,友元函数对某个对象的数据进行操作,就必须通过该对象的名称来进行,因此使用到的参数都要进行传递,操作数的个数就不会有变化。

运算符重载的主要优点就是允许改变使用于系统内部的运算符的操作方式,以适应用户自定义类型的类似运算。

下面我们分别对+,-,++,--,<<运算符分别进行运算符重载,观察程序的结果。


例1:重载+,-

1.使用成员函数实现运算符+,-的重载
#include<iostream>

using namespace std;

class Point {
public:
	Point(int x = 0, int y = 0):x(x),y(y) {};
	Point operator+(Point p) {
		return Point(this->x + p.x, this->y + p.y);
	}
	Point operator-(Point p) {
		return Point(this->x - p.x, this->y - p.y);
	}
	void display() {
		cout << "(" << x << "," << y << ")";
	}

private:
	int x,y;
};

int main()
{
	Point p1(1, 1);
	Point p2(2, 2);
	//1.将友元函数注释,调用Point的成员函数实现 p1 + p2
	Point p3 = p1 + p2;

	cout << "p1:";//输出p1的值
	p1.display();
	cout << " + ";
	cout << "p2:";//输出p2的值
	p2.display();
	cout << " = ";
	cout << "p3:";//输出p3的值
	p3.display();
	cout << endl;

	Point p4 = p1 - p2;

	cout << "p1:";//输出p1的值
	p1.display();
	cout << " - ";
	cout << "p2:";//输出p2的值
	p2.display();
	cout << " = ";
	cout << "p4:";//输出p4的值
	p4.display();
	cout << endl;

	return 0;
}

程序输出:

根据运行结果我们可以看出程序成功的实现了p1+p2和p1-p2。


2.使用友元函数实现运算符+,-的重载
#include<iostream>

using namespace std;

class Point {
	friend Point operator+(Point p1, Point p2); //友元函数
	friend Point operator-(Point p1, Point p2);
public:
	Point(int x = 0, int y = 0):x(x),y(y) {};
	void display() {
		cout << "(" << x << "," << y << ")";
	}

private:
	int x,y;
};

//重载运算符实现
Point operator+(Point p1, Point p2) {
	return Point(p1.x + p2.x, p1.y + p2.y);
}

Point operator-(Point p1, Point p2) {
	return Point(p1.x - p2.x, p1.y - p2.y);
}

int main()
{
	Point p1(1, 1);
	Point p2(2, 2);
	//2.将成语函数注释,调用Point的友元函数实现 p1 + p2
	Point p3 = p1 + p2;
	
	cout << "p1:";//输出p1的值
	p1.display();
	cout << " + ";
	cout << "p2:";//输出p2的值
	p2.display();
	cout << " = ";
	cout << "p3:";//输出p3的值
	p3.display();
	cout << endl;

	Point p4 = p1 - p2;

	cout << "p1:";//输出p1的值
	p1.display();
	cout << " - ";
	cout << "p2:";//输出p2的值
	p2.display();
	cout << " = ";
	cout << "p4:";//输出p4的值
	p4.display();
	cout << endl;

	system("pause");

	return 0;
}

运行结果:


例2:重载++,--

1.使用成员函数重载++
#include<iostream>

using namespace std;

class Point {
	
public:
	Point(int x = 0, int y = 0):x(x),y(y) {};
	Point & operator++() {    //对运算符++(前置)进行重载
		this->x++;
		this->y++;
		return *this;
	}
	Point operator++(int) {  //对运算符++(后置)进行重载
		Point p = *this;
		this->x++;
		this->y++;
		return p;
	}
	void display() {   //输出点
		cout << "(" << x << "," << y << ")" << endl << endl;
	}

private:
	int x,y;
};

int main()
{
	Point p(1, 1);
	cout << "p :";
	p.display();
        
        //p++
	cout << "------ p++ ------" << endl; 

	Point p1 = p++;
	cout << "p1:";
	p1.display();

	cout << "p :";
	p.display();

	cout << "------ p++ ------" << endl << endl;

	cout << "p :";
	p.display();
        
        //++p
	cout << "------ ++p ------" << endl;

	Point p2 = ++p;
	cout << "p2:";
	p2.display();

	cout << "p :";
	p.display();

	cout << "------ ++p ------" << endl << endl;
	
	system("pause");

	return 0;
}

运行结果:


2.使用成员函数重载--
#include<iostream>

using namespace std;

class Point {
	
public:
	Point(int x = 0, int y = 0):x(x),y(y) {};
	Point& operator--() {     //对运算符--(前置)进行重载
		this->x--;
		this->y--;
		return *this;
	}
	Point operator--(int) {    //对运算符--(后置)进行重载
		Point p = *this;
		this->x--;
		this->y--;
		return p;
	}
	void display() {
		cout << "(" << x << "," << y << ")" << endl << endl;
	}

private:
	int x,y;
};

int main()
{
	Point p(1, 1);
	cout << "p :";
	p.display();
        
        //p--
	cout << "------ (p--) ------" << endl;

	Point p1 = p--;
	cout << "p1:";
	p1.display();

	cout << "p :";
	p.display();
        
	cout << "------ (p--) ------" << endl << endl;

	cout << "p :";
	p.display();

	//--p
        cout << "------ (--p) ------" << endl;

	Point p2 = --p;
	cout << "p2:";
	p2.display();

	cout << "p :";
	p.display();

	cout << "------ (--p) ------" << endl << endl;
	
	system("pause");

	return 0;
}

运行结果:


3.使用友元函数重载++
#include<iostream>

using namespace std;

class Point {
	friend Point& operator++(Point& p);     //友元函数
	friend Point operator++(Point& p, int);
public:
	Point(int x = 0, int y = 0) :x(x), y(y) {};
	void display() {
		cout << "(" << x << "," << y << ")" << endl << endl;
	}

private:
	int x, y;
};

Point& operator++(Point &p) {
	p.x++;
	p.y++;
	return p;
}

Point operator++(Point &p, int) {
	Point temp = p;
	p.x++;
	p.y++;
	return temp;
}

int main()
{
	Point p(1, 1);
	cout << "p :";
	p.display();
        
        //p++   
	cout << "------ p++ ------" << endl;

	Point p1 = p++;
	cout << "p1:";
	p1.display();

	cout << "p :";
	p.display();

	cout << "------ p++ ------" << endl << endl;

	cout << "p :";
	p.display();
        
        //++p
	cout << "------ ++p ------" << endl;

	Point p2 = ++p;
	cout << "p2:";
	p2.display();

	cout << "p :";
	p.display();

	cout << "------ ++p ------" << endl << endl;

	system("pause");

	return 0;
}

运行结果:


4.使用友元函数重载--
#include<iostream>

using namespace std;

class Point {
	friend Point& operator--(Point& p);   //友元函数
	friend Point operator--(Point& p, int);
public:
	Point(int x = 0, int y = 0) :x(x), y(y) {};
	void display() {
		cout << "(" << x << "," << y << ")" << endl << endl;
	}

private:
	int x, y;
};

Point& operator--(Point& p) {
	p.x--;
	p.y--;
	return p;
}

Point operator--(Point& p, int) {
	Point temp = p;
	p.x--;
	p.y--;
	return temp;
}

int main()
{
	Point p(1, 1);
	cout << "p :";
	p.display();
        
        //p--
	cout << "------ (p--) ------" << endl;

	Point p1 = p--;
	cout << "p1:";
	p1.display();

	cout << "p :";
	p.display();

	cout << "------ (p--) ------" << endl << endl;

	cout << "p :";
	p.display();
        
        //--p
	cout << "------ (--p) ------" << endl;

	Point p2 = --p;
	cout << "p2:";
	p2.display();

	cout << "p :";
	p.display();

	cout << "------ (--p) ------" << endl << endl;

	system("pause");

	return 0;
}

运行结果:


例3:重载<<运算符实现对Point对象的输出

#include<iostream>

using namespace std;

class Point {
	friend ostream& operator<<(ostream & out, Point& p);    //友元函数
public:
	Point(int x = 0, int y = 0) :x(x), y(y) {};
private:
	int x, y;
};

ostream& operator<<(ostream & out,Point &p) {
	out << "(" << p.x << "," << p.y << ")";
	return out;
}

int main()
{
	Point p(1, 1);
	cout << "p:" << p;    //使用重载后的<<输出p

	system("pause");

	return 0;
}

运行结果:

根据运行结果我们可以看出程序通过<<输出了p的值。

此时我们想到:可不可以使用成员函数重载<<呢?

*使用成员函数重载<<运算符
#include<iostream>

using namespace std;

class Point {
public:
	Point(int x = 0, int y = 0) :x(x), y(y) {};
	void operator<<(ostream& out) {        //使用成员函数进行<<运算符重载
		out << "(" << this->x << "," << this->y << ")";
	}
private:
	int x, y;
};

int main()
{
	Point p(1, 1);
	p << cout;

	system("pause");

	return 0;
}

程序可以正常运行。

但是会出现一个问题,就是程序输出p时只能写成

p << cout

的形式。

因为函数的第一个参数是this指针,第二个参数才是我们传进去的 out,但是这与std中的cout使用习惯完全不符,我们的所打印变量是应该在cout的右边,如 cout<<d<<endl.

这样的重载和普通的函数没有两样,也就失去了重载函数的目的所在。

那么这样,我们便不可以把输出运算符的重载写成成员函数,写成成员函数去实现功能,能实现功能 但失去重载本身的意义。

所以我们应该在类外写重载函数,然后在对应的类中使用友元函数。

以上为我对C++重载运算符知识点的总结。

如有不对,敬请指正。

posted @ 2019-10-27 13:40  美团骑手阿霖  阅读(261)  评论(0编辑  收藏  举报