在C++编程语言中,运算符重载是一项重要的特性,允许程序员根据类的需求自定义运算符的行为。本文将深入探讨如何使用成员函数和友元函数来实现运算符重载,特别是在面向对象方法与C++程序设计中。
当我们谈论运算符重载时,目标是使运算符能作用于我们自定义的数据类型,如类的对象。在给定的描述中,赵小薇教授讲解了大连理工大学面向对象课程中的一个例子,涉及复数类`Complex`。这个例子展示了如何通过成员函数和友元函数来重载加法运算符`+`。
成员函数重载运算符通常在以下情况下使用:
1. 当一元运算符的操作数或者二元运算符的左操作数是类的一个对象时。例如,在`Complex`类中,我们可以重载`+`运算符使其支持两个`Complex`对象的加法,以及一个`Complex`对象与一个实数的加法。成员函数`Complex operator + (Complex &c2)`和`Complex operator + (double d)`分别处理这两种情况。
```cpp
class Complex {
// ...
Complex operator + (Complex &c2);
Complex operator + (double d);
// ...
};
```
成员函数重载的`+`运算符允许我们编写像`k = z + 27`或`k = 27 + z`这样的代码。然而,成员函数重载的运算符不支持交换律,因为它们总是将当前对象作为操作之一。
对于不能使用成员函数重载的情况,例如当运算符的左右操作数类型不同,这时友元函数就派上用场了。友元函数可以访问类的私有和保护成员,因此它们可以处理不同类型的对象。例如,我们可以定义一个友元函数来处理一个实数与一个`Complex`对象的加法:
```cpp
friend Complex operator+(double d1, const Complex &c2);
```
友元函数与成员函数相比,有以下几点区别:
1. 单目运算符通常更适合用成员函数重载,尤其是当运算符需要修改对象状态时。双目运算符既可以是成员函数也可以是友元函数,取决于具体需求。
2. 如果双目运算符的左操作数不是类A的对象,而右操作数是,那么这个运算符不能作为A类的成员函数重载。这是因为成员函数总是以类的对象或其引用作为隐含的第一个操作数。
在`Complex`类的示例中,成员函数`operator +`处理了`Complex`对象之间的加法和`Complex`与实数的加法。而友元函数`operator+`处理了实数与`Complex`对象的加法,使得混合类型运算成为可能。
总结来说,C++中的运算符重载通过成员函数和友元函数提供了一种灵活的方式来扩展类的行为,使得自定义数据类型可以像内置类型一样进行运算。成员函数适用于操作对象自身,而友元函数则用于处理跨类型的运算。理解这两者的使用场景和限制是掌握C++面向对象编程的关键。