重载运算符
-
重载运算符的本质是
函数
,其名字由operator关键字
后接表示要定义的运算符的符号组成。 -
因此,赋值运算符就是一个名为
operator=
的函数。 -
类似于任何其他的函数,重载运算符函数也有一个返回类型和一个参数列表。
-
重载运算符的
参数
是表示重载运算符要去操作的运算对象。对于某些运算符,包括赋值运算符,都必须定义为成员函数。
运算符重载
运算符重载是C++中的一种特性,它允许我们为自定义数据类型(如类和结构)定义运算符的行为。这意味着我们可以使用现有的运算符来操作我们定义的类型,使代码更加直观和易于理解。
让我们从一个简单的示例开始,创建一个名为“Fraction”的分数类,我们将重载加法运算符(+)来处理两个分数的相加。
#include <iostream>
class Fraction {
public:
// 构造函数
Fraction(int numerator, int denominator) : numerator_(numerator), denominator_(denominator) {}
// 获取分子
int GetNumerator() const {
return numerator_;
}
// 获取分母
int GetDenominator() const {
return denominator_;
}
// 重新定义 Fraction 这个类型的 + 运算符。
Fraction operator+(const Fraction& other) const {
int commonDenominator = denominator_ * other.denominator_;
int newNumerator = (numerator_ * other.denominator_) + (other.numerator_ * denominator_);
return Fraction(newNumerator, commonDenominator);
}
private:
int numerator_; //分子
int denominator_; //分母
};
int main() {
Fraction frac1(1, 2);
Fraction frac2(1, 3);
Fraction result = frac1 + frac2; // 使用重载后的加法运算符
std::cout << "Result: " << result.GetNumerator() << "/" << result.GetDenominator() << std::endl;
return 0;
}
-
在这个例子中,我们定义了一个名为
Fraction
的类,它有两个私有成员变量:numerator_(分子)和denominator_(分母)
。我们还定义了一个名为operator+
的成员函数,它接受一个Fraction
对象的引用作为参数,并返回一个新的Fraction
对象。这个函数的实现是根据两个分数的加法规则计算出新的分子和分母。 -
在main()函数中,我们创建了两个Fraction对象,
并使用重载的加法运算符(+)将它们相加
。最后,我们将结果打印到控制台。 -
这只是一个简单的示例,C++允许我们重载许多不同的运算符,例如
-、*、/、%、==、!=、<、>、<=、>=、++、--、+=、-=、*=、/=、%=、&、|、^、~、<<、>>、>>=、<<=、!、&&、||、[]、()、->、->*、,和new、delete、new[]、delete[]
等等。
需要遵守的原则
- 当重载运算符时,请确保您遵循一些基本原则:
-
保持操作符的语义
:尽量让重载的运算符具有类似的行为和语义,以避免引入混淆或误导性的代码。 -
不要滥用运算符重载
:虽然运算符重载可以让代码更易读,但不当使用会导致代码难以理解。请确保重载的运算符适用于您的类,并确保其实现与期望的行为一致。 -
使用成员函数和非成员函数进行重载
:某些运算符应该作为类的成员函数重载(例如 +=、-=),而另一些运算符应该作为非成员函数重载(例如 +、-)。这取决于运算符的语义以及您希望在类之外使用哪些重载运算符。
以下是另一个Fraction类的示例,这次我们将添加一个友元函数来重载输出运算符(<<):
#include <iostream>
#include <string>
using namespace std;
class Fraction {
public:
Fraction(int numerator, int denominator) : numerator_(numerator), denominator_(denominator) {}
int GetNumerator() const {
return numerator_;
}
int GetDenominator() const {
return denominator_;
}
Fraction operator+(const Fraction& other) const {
int commonDenominator = denominator_ * other.denominator_;
int newNumerator = (numerator_ * other.denominator_) + (other.numerator_ * denominator_);
return Fraction(newNumerator, commonDenominator);
}
// 重载输出运算符(友元函数)
friend std::ostream& operator<<(std::ostream& os, const Fraction& fraction);
private:
int numerator_;
int denominator_;
};
// 实现重载输出运算符(非成员函数)
std::ostream& operator<<(std::ostream& os, const Fraction& fraction) {
os << fraction.numerator_ << "/" << fraction.denominator_;
return os;
}
int main() {
Fraction frac1(1, 2);
Fraction frac2(1, 3);
cout<<"frac1 = "<<frac1<<endl;
cout<<"frac2 = "<<frac2<<endl;
Fraction result = frac1 + frac2;
std::cout << "Result = " <<frac1<<" + "<<frac2<<" = "<< result << std::endl; // 使用重载的输出运算符
return 0;
}
- 在这个例子中,我们添加了一个名为
operator<<
的友元函数,用于重载输出运算符。这使得我们可以直接在std::cout语句中输出Fraction对象,而不需要调用GetNumerator()
和GetDenominator()
函数。
总之,运算符重载是C++中一种强大的特性,可以让我们为自定义类型定义运算符的行为。请务必合理地使用这个特性,以便编写出易于阅读和理解的代码。
总结
我原来在看C++Primer5的时候,第一开始就给我一堆我看不懂的代码,然后其中最看不懂的就是这个operator关键字,原来我还不知道是啥意思,今天我死磕了好几个小时,终于给我弄懂了!!!