Skip to content

运算符重载

1.概念及语法

运算符重载,就是在一个类中对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。

运算符重载(operator overloading)只是一种"语法上的方便”,也就是它只是另一种函数调用的方式

c++中,可以定义一个处理类的新运算符。这种定义很像一个普通的函数定义,只是函数的名字由关键字operator及其紧跟的运算符组成。差别仅此而已。它像任何其他函数一样也是一个函数,当编译器遇到适当的模式时,就会调用这个函数。

语法:

定义重载的运算符就像定义函数

c++
class MyClass{
    返回值类型 operator运算符(参数列表){
    	// ...
	}
}

注意

当函数在类外定义时,运算符是几元,就写几个参数,参数的顺序即运算符使用时从左到右的顺序

当函数为成员函数时,第一个参数不用写,可以使用用this代替

2.可重载的运算符

image-20240722143440065

运算符类别运算符种类
双目算术运算符+ (加),-(减),*(乘),/(除),% (取模)
关系运算符==(等于),!= (不等于),< (小于),> (大于),<=(小于等于),>=(大于等于)
逻辑运算符||(逻辑或),&&(逻辑与),!(逻辑非)
单目运算符+ (正),-(负),*(指针),&(取地址)
自增自减运算符++(自增),--(自减)
位运算符| (按位或),& (按位与),~(按位取反),^(按位异或),,<< (左移),>>(右移)
赋值运算符=, +=, -=, *=, /= , % = , &=, |=, ^=, <<=, >>=
空间申请与释放new, delete, new[ ] , delete[]
其他运算符()(函数调用),->(成员访问),,(逗号),[](下标)

3.不可重载的运算符

image-20240722143500211

  • .:成员访问运算符
  • .*, ->*:成员指针访问运算符
  • :::域运算符
  • sizeof:长度运算符
  • ?::条件运算符
  • #: 预处理符号

4.重载运算符

4.1 二元运算符重载

c++
#include<iostream>
using namespace std;

class Point {
public:
	int x;
	int y;
	Point(int x, int y) :x(x), y(y) {}
	Point operator-(Point p) {
		return { x - p.x,y - p.y };
	}
};

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

int main() {
	Point p1(10, 20);
	Point p2(5, 15);

	Point p3 = p1 + p2;
	cout << p3.x << endl;  // 15
	cout << p3.y << endl;  // 35

	Point p4 = p1 - p2;
	cout << p4.x << endl;  // 5
	cout << p4.y << endl;  // 5
	return 0;
}

以上方法当调用重载的运算符时

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

Point p3 = p1 + p2;

在函数的传参时,相当于发生了如下逻辑

假设=的左值为形参,右值为实参

c++
Point operator+ (Point p1 = p1, Point p2 = p2) {
    // ...
}

这样,则开辟了两处内存空间,为了节省空间,提升效率,我们需要用到引用,而为了防止实参内容的更改,我们需要用到const

c++
Point operator+ (const Point &p1, const Point &p2) {
	return { p1.x + p2.x,p1.y + p2.y };
}

这样,在函数传参时,就不会开辟多余的空间

4.2 一元运算符重载

4.2.1 运算符前置

c++
#include<iostream>
using namespace std;

class Point {
public:
	int x;
	int y;
	Point(int x, int y) :x(x), y(y) {}
	Point operator --() {
		x--;
		y--;
		return *this;
	}
};

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

int main() {
	Point p1(5, 15);
	Point p2 = ++p1;

	cout << p1.x << endl;		// 6
	cout << p1.y << endl;		// 16

	cout << p2.x << endl;		// 6
	cout << p2.y << endl;		// 16


	Point p3(5, 15);
	Point p4 = --p3;

	cout << p3.x << endl;		// 4
	cout << p3.y << endl;		// 14

	cout << p4.x << endl;		// 5
	cout << p4.y << endl;		// 14
	return 0;
}

4.2.1 运算符后置

注意,int 在 括号内是为了向编译器说明这是一个后缀形式,而不是表示整数。

c++
#include<iostream>
using namespace std;

class Point {
public:
	int x;
	int y;
	Point(int x, int y) :x(x), y(y) {}
	Point operator --(int) {
		Point temp = *this;
		x--;
		y--;
		return temp;
	}
};

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

int main() {
	Point p1(5, 15);
	Point p2 = p1++;

	cout << p1.x << endl;		// 6
	cout << p1.y << endl;		// 16

	cout << p2.x << endl;		// 5
	cout << p2.y << endl;		// 15

	Point p3(5, 15);
	Point p4 = p3--;

	cout << p3.x << endl;		// 4
	cout << p3.y << endl;		// 14

	cout << p4.x << endl;		// 5
	cout << p4.y << endl;		// 15

	return 0;
}

4.3 输入/输出运算符重载

C++ 能够使用流提取运算符 >> 和流插入运算符 << 来输入和输出内置的数据类型。您可以重载流提取运算符和流插入运算符来操作对象等用户自定义的数据类型。

在这里,有一点很重要,我们需要把运算符重载函数声明为类的友元函数,这样我们就能不用创建对象而直接调用函数。

下面的实例演示了如何重载提取运算符 >> 和插入运算符 <<。

c++
#include <iostream>
using namespace std;
 
class Distance
{
   private:
      int feet;             // 0 到无穷
      int inches;           // 0 到 12
   public:
      // 所需的构造函数
      Distance(){
         feet = 0;
         inches = 0;
      }
      Distance(int f, int i){
         feet = f;
         inches = i;
      }
      friend ostream &operator<<( ostream &output, const Distance &D ){ 
         output << "F : " << D.feet << " I : " << D.inches;
         return output;            
      }
 
      friend istream &operator>>( istream  &input, Distance &D ) { 
         input >> D.feet >> D.inches;
         return input;            
      }
};
int main()
{
   Distance D1(11, 10), D2(5, 11), D3;
 
   cout << "First Distance : " << D1 << endl;
   cout << "Second Distance :" << D2 << endl;
    
   cout << "Enter the value of object : " << endl;
   cin >> D3;
   cout << "Third Distance :" << D3 << endl;
 
   return 0;
}

4.4 赋值运算符重载

c++
#include <iostream>
using namespace std;
 
class Distance
{
   private:
      int feet;             // 0 到无穷
      int inches;           // 0 到 12
   public:
      // 所需的构造函数
      Distance(){
         feet = 0;
         inches = 0;
      }
      Distance(int f, int i){
         feet = f;
         inches = i;
      }
      void operator=(const Distance &D ) { 
         feet = D.feet;
         inches = D.inches;
      }
      // 显示距离的方法
      void displayDistance()
      {
         cout << "F: " << feet <<  " I:" <<  inches << endl;
      }
      
};
int main()
{
   Distance D1(11, 10), D2(5, 11);
 
   cout << "First Distance : "; 
   D1.displayDistance();
   cout << "Second Distance :"; 
   D2.displayDistance();
 
   // 使用赋值运算符
   D1 = D2;
   cout << "First Distance :"; 
   D1.displayDistance();
 
   return 0;
}

MIT Licensed