往期回顾:
一、前言
在前面的文章学习中,我们学习了类和对象的基础知识以及构造函数、拷贝构造函数、静态成员和常量成员。今天,我们将深入学习运算符重载。运算符重载是 C++ 的一大特色,它使得我们可以对类对象使用类似于基本数据类型的运算符,从而使代码更加简洁和易读。
二、运算符重载
2.1、 什么是运算符重载?
运算符重载是C++中一个强大且灵活的特性,它允许开发者为自定义类型(如类)重新定义或“重载”C++中已有的运算符。这种机制极大地增强了代码的可读性和易用性,使得针对自定义类型的操作能够以一种类似于内置数据类型(如int、float等)的方式来进行。
2.2、为什么要进行运算符重载?
直观性: | 通过重载运算符,可以使类对象之间的操作看起来就像是对内置数据类型的操作一样,从而提高代码的可读性和可维护性。例如,如果定义了一个复数类,那么重载加法运算符+ 就可以让两个复数对象的相加看起来就像是对两个整数的相加一样直观。 |
一致性: | 在C++中,内置数据类型的运算符行为是预定义的。通过为自定义类型重载这些运算符,可以确保自定义类型与内置类型在表达和操作上的一致性,从而简化编程模型。 |
封装性: | 运算符重载提供了一种封装复杂操作的方式。通过将复杂的逻辑隐藏在简单的运算符背后,可以隐藏类的内部实现细节,只暴露必要的接口给使用者。 |
2.3、如何进行运算符重载?
运算符重载是通过在类中定义特殊的成员函数(称为运算符函数)来实现的。这些函数的名字由关键字operator
后跟要重载的运算符符号组成。运算符函数可以是成员函数,也可以是友元函数,具体取决于运算符的操作是否需要访问类的私有或保护成员。
2.4、运算符重载的规则和限制
不可重载的运算符:并非所有C++运算符都可以被重载。例如,
.
(成员访问运算符)、.*
(成员指针访问运算符)、::
(作用域解析运算符)、sizeof
(大小运算符)、typeid
(类型识别运算符)以及几个与对象构造和析构相关的运算符(如new
和delete
)都不能被重载。运算符的语义:虽然可以重载运算符,但应该保持运算符的原有语义,即该运算符在被重载后应该继续表达相似的操作或逻辑。这有助于避免混淆和误解。
参数数量和类型:除了赋值运算符
=
、下标运算符[]
、函数调用运算符()
和成员访问运算符->*
之外,大多数运算符函数只能有一个(对于一元运算符)或两个(对于二元运算符)参数。这些参数的类型和数量是固定的,不能随意改变。返回类型:运算符函数的返回类型也是根据被重载的运算符而定的。例如,算术运算符(如
+
、-
、*
、/
)通常返回操作数的类型或其某种形式的转换类型。友元函数:有时,为了重载的运算符能够访问类的私有或保护成员,可能需要将运算符函数声明为类的友元函数。
通过运算符重载,C++提供了一种强大的机制来扩展其语言特性,使得自定义类型能够以一种更加直观和自然的方式与内置类型进行交互。
2.5、运算符重载的语法
运算符重载是通过在类中定义特殊的成员函数来实现的。语法格式如下:
返回类型 operator运算符(参数列表) {
// 函数体
}
其中,operator
关键字后面跟着要重载的运算符。例如,要重载加法运算符 +
,则函数名为 operator+
。
A、重载加法运算符(+)
我们先来看看如何重载加法运算符。假设有一个 Complex
类,用于表示复数。
示例:
#include <iostream>
using namespace std;
class Complex {
public:
double real;
double imag;
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
// 重载加法运算符
Complex operator+(const Complex &c) const {
return Complex(real + c.real, imag + c.imag);
}
void display() const {
cout << "(" << real << ", " << imag << "i)" << endl;
}
};
int main() {
Complex c1(3.0, 4.0);
Complex c2(1.5, 2.5);
Complex c3 = c1 + c2; // 使用重载的加法运算符
c1.display();
c2.display();
c3.display();
return 0;
}
在这个示例中,我们定义了一个 Complex
类,并重载了加法运算符。重载的 operator+
函数接受一个 Complex
对象作为参数,并返回一个新的 Complex
对象,其实部和虚部分别为两个操作数的对应部分之和。
B、重载减法运算符(-)
类似于加法运算符,我们也可以重载减法运算符。
示例:
#include <iostream>
using namespace std;
class Complex {
public:
double real;
double imag;
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
// 重载加法运算符
Complex operator+(const Complex &c) const {
return Complex(real + c.real, imag + c.imag);
}
// 重载减法运算符
Complex operator-(const Complex &c) const {
return Complex(real - c.real, imag - c.imag);
}
void display() const {
cout << "(" << real << ", " << imag << "i)" << endl;
}
};
int main() {
Complex c1(3.0, 4.0);
Complex c2(1.5, 2.5);
Complex c3 = c1 + c2; // 使用重载的加法运算符
Complex c4 = c1 - c2; // 使用重载的减法运算符
c1.display();
c2.display();
c3.display();
c4.display();
return 0;
}
在这个示例中,我们在 Complex
类中重载了减法运算符 operator-
,使得两个 Complex
对象可以相减。
2. 6、重载赋值运算符(=)
赋值运算符 =
用于将一个对象的值赋给另一个对象。默认情况下,C++ 提供了一个默认的赋值运算符,但在某些情况下,我们需要自定义赋值运算符。
A、重载赋值运算符的语法
语法格式如下:
ClassName &operator=(const ClassName &other) {
// 函数体
return *this;
}
示例:
#include <iostream>
using namespace std;
class Complex {
public:
double real;
double imag;
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
// 重载赋值运算符
Complex &operator=(const Complex &c) {
if (this == &c) // 防止自我赋值
return *this;
real = c.real;
imag = c.imag;
return *this;
}
void display() const {
cout << "(" << real << ", " << imag << "i)" << endl;
}
};
int main() {
Complex c1(3.0, 4.0);
Complex c2;
c2 = c1; // 使用重载的赋值运算符
c1.display();
c2.display();
return 0;
}
在这个示例中,我们在 Complex
类中重载了赋值运算符 operator=
,使得可以将一个 Complex
对象的值赋给另一个 Complex
对象。注意在赋值运算符中,我们需要检查是否是自我赋值,如果是,则直接返回当前对象。
以上就是 C++ 程序的运算符重载的基础知识点了。包括重载加法运算符、减法运算符和赋值运算符。运算符重载使得我们可以对类对象进行类似于基本数据类型的操作,从而使代码更加简洁和易读。
都看到这里了,点个赞再走呗朋友~
加油吧,预祝大家变得更强!