在 C++ 中,我们可以定义运算符如何作用于用户定义的类型,如 类和 结构。例如:
当 +
运算符用于 int
类型的值时,它会返回它们的和。但是,当它用于用户定义类型的对象时,则会引发错误。
在这种情况下,我们可以定义 +
运算符的行为,使其也能用于对象。
这种让运算符作用于对象和结构变量的概念称为 **运算符重载**。
C++ 运算符重载的语法
重载运算符的语法类似于 函数,只是增加了 operator
关键字,后面跟着运算符符号。
returnType operator symbol (arguments) {
... .. ...
}
这里,
returnType
- 函数的返回类型operator
- 一个特殊的 关键字symbol
- 我们要重载的运算符(+
、<
、-
、++
等)arguments
- 传递给函数的参数
重载二进制 +
运算符
以下程序演示了如何为 Complex
类重载 +
运算符。
// C++ program to overload the binary operator +
// This program adds two complex numbers
#include <iostream>
using namespace std;
class Complex {
private:
float real;
float img;
public:
// constructor to initialize real and img to 0
Complex() : real(0), img(0) {}
Complex(float real, float img) : real(real), img(img){}
// overload the + operator
friend Complex operator + (const Complex& obj1, const Complex& obj2) {
Complex temp;
temp.real = obj1.real + obj2.real;
temp.img = obj1.img + obj2.img;
return temp;
}
void display() {
if (img < 0)
cout << "Output Complex number: " << real << img << "i";
else
cout << "Output Complex number: " << real << "+" << img << "i";
}
};
int main() {
Complex c1(1.0f, 2.0f);
Complex c2(1.0f, 3.0f);
// calls the overloaded + operator
Complex result = c1 + c2;
result.display();
return 0;
}
输出
Output Complex number: 2+5i
在这里,我们首先创建了一个返回类型为 Complex
的友元函数。
friend Complex operator + () {
...
}
operator
关键字后跟 +
表示我们正在重载 +
运算符。
该函数接受两个参数
friend Complex operator + (const Complex& obj1, const Complex& obj2) {...}
这里,
Complex&
表示我们通过引用传递对象,并且 obj1 和 obj2 是Complex
对象的引用。这是一种高效的方法,因为它可以避免不必要的复制,特别是对于大对象。要了解更多信息,请访问 C++ 引用。
const
表示引用的对象是常量,这意味着我们不能在函数中修改 obj1 和 obj2。
在函数内部,我们创建了另一个 Complex
对象 temp 来存储加法结果。
Complex temp;
然后,我们将两个对象的实部相加,并将结果存储到 temp 对象的 real
属性中。
temp.real = obj1.real + obj2.real;
同样,我们将两个对象的虚部相加,并将它们存储到 temp 对象的 img
属性中。
temp.img = obj1.img + obj2.img;
最后,我们从函数返回 temp 对象。
return temp;
我们也可以使用成员函数而不是友元函数来重载运算符。例如:
class Complex{
…..
public:
Complex operator + (const Complex& obj){
Complex temp;
temp.real = real + obj.real;
temp.img = img + obj.img;
return temp;
}
…….
};
在这种情况下,运算符由第一个操作数调用。这意味着,行
Complex c3 = c1 + c2;
被翻译为
c1.operator+(c2);
在这里,运算符函数的参数数量减少了一个,因为第一个参数用于调用函数。
这种方法的缺点是,第一个操作数并不总是用户定义类型的对象。例如:
c2 = 1 + c1;
这就是为什么通常建议将运算符函数重载为非成员函数,并将其定义为友元函数。
重载 ++
作为前缀运算符
以下程序演示了为 Count
类重载 ++
运算符。
// Overload ++ when used as a prefix operator
#include <iostream>
using namespace std;
class Count {
private:
int value;
public:
// constructor to initialize count to 5
Count() : value(5) {}
// overload ++ when used as prefix
void operator ++ () {
++value;
}
void display() {
cout << "Count: " << value << endl;
}
};
int main() {
Count count1;
// call the "void operator ++ ()" function
++count1;
count1.display();
return 0;
}
输出
Count: 6
在这里,当我们使用 ++count1;
时,会调用 void operator ++ ()
。这将 count1 对象的值属性增加 1。
注意:重载运算符时,我们可以随意使用它们。例如,我们可以使用 ++ 将值增加 100。
然而,这会使我们的代码令人困惑且难以理解。作为程序员,我们的工作是正确地、以一致且直观的方式使用运算符重载。
++
作为后缀运算符要将 ++
运算符重载为后缀运算符,我们需要声明一个成员函数 operator++()
,该函数接受一个类型为 int
的参数。
// Overload ++ when used as postfix operator
#include <iostream>
using namespace std;
class Count {
private:
int value;
public:
// constructor to initialize count to 5
Count() : value(5) {}
// overload ++ used as postfix
void operator ++ (int) {
value++;
}
void display() {
cout << "Count: " << value << endl;
}
};
int main() {
Count count1;
// call the "void operator ++ (int)" function
count1++;
count1.display();
count1.display();
return 0;
}
输出
Count: 6 Count: 7
在这里,当我们使用 count1++;
时,会调用 void operator ++ (int)
。这将 count1 对象的值属性增加 1。
注意:参数 int 仅用于指示运算符被用作后缀运算符。
C++ 运算符重载需要注意的事项
1. 默认情况下,C++ 中 =
和 &
运算符已重载。例如:
我们可以直接使用 =
运算符来复制同一类的对象。在这里,我们不需要创建运算符函数。
2. 我们不能使用运算符重载来更改运算符的优先级和结合性。
3. 我们不能在 C++ 中重载以下运算符:
::
(作用域解析).
(成员选择).*
(通过指向函数的指针进行成员选择)?:
(三元运算符)sizeof
运算符typeid
运算符
4. 我们不能为基本数据类型(如 int
、float
等)重载运算符。
另请阅读