18、运算符重载
大约 3 分钟C++C++基础编程程序厨
通过运算符重载,程序员可以为用户自定义类型(如类或结构体)定义运算符,使代码的行为更容易理解。
运算符重载的概念与语法
概念
运算符重载是指为自定义类型重新定义C++
内置运算符的行为。例如,可以通过重载+
运算符,使两个自定义类型的对象能够像基本数据类型一样进行加法运算。
语法
运算符重载通过定义特殊的成员函数或全局函数来实现。重载运算符的函数名由关键字operator
和要重载的运算符组成。
成员函数形式
返回类型 operator运算符(参数列表);
全局函数形式
返回类型 operator运算符(参数1, 参数2);
常见运算符的重载实现
+
、-
、*
、/
)
算术运算符重载(示例:复数类的加法运算符重载
#include <iostream>
using namespace std;
class Complex {
private:
double real;
double imag;
public:
Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}
// 成员函数形式重载+
Complex operator+(const Complex& other) {
return Complex(real + other.real, imag + other.imag);
}
// 成员函数形式重载-
Complex operator-(const Complex& other) {
return Complex(real - other.real, imag - other.imag);
}
void display() {
cout << real << " + " << imag << "i" << endl;
}
};
int main() {
Complex c1(3.0, 4.0);
Complex c2(1.0, 2.0);
Complex c3 = c1 + c2; // 使用重载的+运算符
c3.display(); // 输出:4 + 6i
Complex c4 = c1 - c2; // 使用重载的-运算符
c4.display(); // 输出:2 + 2i
return 0;
}
==
、!=
、<
、>
)
关系运算符重载(示例:复数类的相等运算符重载
#include <iostream>
using namespace std;
class Complex {
private:
double real;
double imag;
public:
Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}
// 成员函数形式重载==
bool operator==(const Complex& other) {
return (real == other.real) && (imag == other.imag);
}
// 成员函数形式重载!=
bool operator!=(const Complex& other) {
return !(*this == other);
}
void display() {
cout << real << " + " << imag << "i" << endl;
}
};
int main() {
Complex c1(3.0, 4.0);
Complex c2(3.0, 4.0);
Complex c3(1.0, 2.0);
if (c1 == c2) {
cout << "c1 and c2 are equal." << endl;
} else {
cout << "c1 and c2 are not equal." << endl;
}
if (c1 != c3) {
cout << "c1 and c3 are not equal." << endl;
} else {
cout << "c1 and c3 are equal." << endl;
}
return 0;
}
=
)
赋值运算符重载(示例:字符串类的赋值运算符重载
#include <iostream>
#include <cstring>
using namespace std;
class MyString {
private:
char* str;
public:
MyString(const char* s = "") {
str = new char[strlen(s) + 1];
strcpy(str, s);
}
// 析构函数
~MyString() {
delete[] str;
}
// 赋值运算符重载
MyString& operator=(const MyString& other) {
if (this == &other) {
return *this; // 处理自我赋值
}
delete[] str; // 释放原有内存
str = new char[strlen(other.str) + 1];
strcpy(str, other.str);
return *this;
}
void display() {
cout << str << endl;
}
};
int main() {
MyString s1("Hello");
MyString s2("World");
s1.display(); // 输出:Hello
s2.display(); // 输出:World
s2 = s1; // 使用重载的=运算符
s2.display(); // 输出:Hello
return 0;
}
<<
、>>
)
流插入和流提取运算符重载(示例:复数类的流提取运算符重载
#include <iostream>
using namespace std;
class Complex {
private:
double real;
double imag;
public:
Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}
// 友元函数形式重载<<
friend ostream& operator<<(ostream& os, const Complex& c);
};
ostream& operator<<(ostream& os, const Complex& c) {
os << c.real << " + " << c.imag << "i";
return os;
}
int main() {
Complex c;
cout << c << endl; // 使用重载的<<运算符
return 0;
}
注意事项与限制
注意事项
- 保持语义一致性:重载的运算符应与其原始语义一致。例如,
+
运算符应实现加法操作,而不是减法操作。 - 处理自我赋值:在重载赋值运算符时,需要处理自我赋值的情况。
限制
- 以下运算符不能重载:
- 成员访问运算符(
.
) - 成员指针访问运算符(
.*
) - 作用域解析运算符(
::
) - 条件运算符(
?:
) sizeof
运算符
- 成员访问运算符(
- 不能改变运算符的优先级和结合性:重载运算符的优先级和结合性与原始运算符相同。
- 至少有一个操作数是用户自定义类型:不能为基本数据类型重载运算符。
练习
- 设计一个
Matrix
类,重载+
、-
、*
运算符,实现矩阵的加法、减法和乘法运算。 - 实现一个
Fraction
类,重载+
、-
、*
、/
运算符,实现分数的加减乘除运算。 - 设计一个
Date
类,重载++
和--
运算符,实现日期的递增和递减操作。
