目录
一、C++ 魔法师的新工具:操作符重载
1.1 操作符重载初印象
在 C++ 的奇妙世界里,操作符重载就像是给魔法师的魔杖赋予了新的魔力。我们都熟悉普通的算术操作符,比如+、-、*、/,它们可以对基本数据类型(如int、double)进行运算。但是,当我们定义了自己的类或结构体时,这些操作符并不能直接应用于我们自定义的数据类型。操作符重载就解决了这个问题,它允许我们重新定义操作符的行为,使其能够适用于自定义类型。
例如,我们定义一个表示二维向量的类Vector2D:
class Vector2D {
public:
double x;
double y;
Vector2D(double _x, double _y) : x(_x), y(_y) {}
};
如果我们想要实现两个Vector2D对象的相加,就像普通的数学向量相加一样,该怎么办呢?这时候操作符重载就派上用场了。我们可以重载+操作符,让它实现向量相加的功能:
Vector2D operator+(const Vector2D& a, const Vector2D& b) {
return Vector2D(a.x + b.x, a.y + b.y);
}
这样,我们就可以像使用普通的加法操作符一样,对Vector2D对象进行相加:
Vector2D v1(1.0, 2.0);
Vector2D v2(3.0, 4.0);
Vector2D v3 = v1 + v2; // 调用重载的+操作符
操作符重载不仅让代码看起来更加简洁和直观,还增强了代码的可读性和可维护性。它让我们能够以一种自然的方式与自定义数据类型进行交互,就像使用内置数据类型一样。
1.2 重载规则大揭秘
虽然操作符重载很强大,但它也有一些规则需要遵循,就像魔法师使用魔法也要遵守魔法世界的规则一样。
-
不能创建新操作符:我们只能重载已有的操作符,比如+、-、*等,不能创造一个全新的操作符,比如**(求幂)这种在 C++ 中原本不存在的操作符。
-
不能改变操作符的优先级和结合性:操作符的优先级和结合性是固定的,比如乘法*的优先级高于加法+,这在重载操作符后也不会改变。例如,a + b * c 无论a、b、c是何种类型,都会先计算b * c,再与a相加。
-
操作数个数不能改变:一元操作符(如!、-)只能重载为一元操作符,二元操作符(如+、-、*、/)只能重载为二元操作符,不能改变它们的操作数个数。比如,不能把二元的+重载为一元操作符。
-
部分操作符不能重载:像作用域解析操作符::、成员选择操作符.、sizeof、三元操作符? :和成员指针选择器.*这些操作符是不能被重载的。
下面是一个简单的代码示例,展示了重载操作符不能改变优先级的规则:
class Number {
public:
int value;
Number(int _value) : value(_value) {}
// 重载加法操作符
Number operator+(const Number& other) const {
return Number(value + other.value);
}
// 重载乘法操作符
Number operator*(const Number& other) const {
return Number(value * other.value);
}
};
int main() {
Number a(2);
Number b(3);
Number c(4);
// 这里会先计算b * c,再与a相加,符合乘法优先级高于加法
Number result = a + b * c;
return 0;
}
1.3 常见操作符重载实例
在实际编程中,我们经常会重载一些常见的操作符,以满足不同的需求。
- 算术操作符重载:除了前面提到的+操作符,还可以重载-(减法)、*(乘法)、/(除法)等算术操作符。以复数类Complex为例,我们可以重载这些操作符来实现复数的四则运算:
class Complex {
public:
double real;
double imag;
Complex(double _real, double _imag) : real(_real), imag(_imag) {}
// 重载加法操作符
Complex operator+(const Complex& other) const {
return Complex(real + other.real, imag + other.imag);
}
// 重载减法操作符
Complex operator-(const Complex& other) const {
return Complex(real - other.real, imag - other.imag);
}
// 重载乘法操作符
Complex operator*(const Complex& other) const {
return Complex(real * other.real - imag * other.imag, real * other.imag + imag * other.real);
}
// 重