友元函数的运算符重载

一、友元函数的运算符重载

定义和用途

友元函数用于运算符重载时,可以访问类的私有和保护成员。这在一些情况下非常有用,特别是当需要访问多个类的私有成员时。例如,实现两个类对象之间的加法运算,或者实现全局运算符函数。

语法和实现

友元函数的运算符重载通常包括以下几个步骤:

  1. 在类声明中声明友元函数。
  2. 在类外部定义友元函数,实现具体的运算符重载逻辑。

二、实现步骤

假设我们有一个 Vector 类,代表二维向量,其中包括两个私有成员 xy。我们希望实现向量的加法操作,并使用友元函数对加法运算符进行重载。

  1. 定义 Vector:定义一个 Vector 类,其中包括两个私有成员 xy,以及一个友元函数的声明。

    class Vector {
    private:
        double x, y;
    public:
        // 构造函数
        Vector(double x = 0, double y = 0) : x(x), y(y) {}
    
        // 友元函数声明
        friend Vector operator+(const Vector& v1, const Vector& v2);
    
        // 打印向量
        void print() const {
            cout << "(" << x << ", " << y << ")" << endl;
        }
    };
  2. 声明友元函数:在 Vector 类中声明一个友元函数,以便该函数可以访问 Vector 类的私有成员。这里我们将声明一个友元函数 operator+,用于重载 + 运算符。

    // 友元函数声明
        friend Vector operator+(const Vector& v1, const Vector& v2);
    
  3. 定义友元函数:在 Vector 类外部定义友元函数,实现对 + 运算符的重载操作。在该函数中,我们需要访问 Vector 类的私有成员,因此使用了友元函数。

    // 友元函数定义,用于重载+运算符
    Vector operator+(const Vector& v1, const Vector& v2) {
        return Vector(v1.x + v2.x, v1.y + v2.y);
    }

三、使用友元函数重载的优点

  1. 访问私有成员:友元函数可以访问类的私有成员和保护成员。在某些情况下,需要在类外部定义函数来操作类的私有成员。使用友元函数可以方便地实现对私有成员的访问,从而进行运算符重载。

  2. 多个类之间的操作:有时候,运算符重载涉及多个类之间的操作。例如,实现两个类的对象之间的加法运算。此时,可以使用一个类的友元函数来访问另一个类的私有成员,以便进行运算。

  3. 增强封装性:虽然友元函数可以访问类的私有成员,但它们不是类的成员函数。因此,使用友元函数可以提供一定程度的封装性,避免将所有操作都作为类的成员函数公开。

  4. 提高灵活性:有时候,通过友元函数对运算符进行重载可以提高代码的灵活性和可读性。可以将某些与类相关但不属于类成员函数的操作定义为友元函数,使得代码更清晰。

四、代码示例

重载前置单目运算符 ‘--’
#include <iostream>
using namespace std;

class Counter {
private:
    int value;
public:
    // 构造函数
    Counter(int v = 0) : value(v) {}

    // 友元函数声明
    friend Counter& operator--(Counter& c); // 前置递减

    // 打印值
    void print() const {
        cout << value << endl;
    }
};

// 友元函数定义,用于重载前置递减运算符
Counter& operator--(Counter& c) {
    --c.value;
    return c;
}

int main() {
    Counter c(5);
    --c;  // 使用重载的前置递减运算符

    cout << "c after --c: ";
    c.print();

    return 0;
}
重载后置单目运算符 ‘--’
#include <iostream>
using namespace std;

class Counter {
private:
    int value;
public:
    // 构造函数
    Counter(int v = 0) : value(v) {}

    // 友元函数声明
    friend Counter operator--(Counter& c, int); // 后置递减

    // 打印值
    void print() const {
        cout << value << endl;
    }
};

// 友元函数定义,用于重载后置递减运算符
Counter operator--(Counter& c, int) {
    Counter temp = c;
    c.value--;
    return temp;
}

int main() {
    Counter c(5);
    Counter c_old = c--;  // 使用重载的后置递减运算符

    cout << "c after c--: ";
    c.print();
    cout << "old c: ";
    c_old.print();

    return 0;
}

小结:由于友元运算符重载函数没有this指针,所以不能引用this指针所指的对象。使用友元函数重载自增运算符‘++’或自减运算符‘--’时,应采用对象引用参数传递数据。例如:
friend Three operator++(Three &);//前缀方式

friend Three operator++(Three &,int);//后缀方式

重载双目运算符‘+’ 
#include <iostream>
using namespace std;

class Vector {
private:
    double x;
    double y;
public:
    // 构造函数
    Vector(double x = 0, double y = 0) : x(x), y(y) {}

    // 友元函数声明
    friend Vector operator+(const Vector& v1, const Vector& v2);

    // 打印向量
    void print() const {
        cout << "(" << x << ", " << y << ")" << endl;
    }
};

// 友元函数定义,用于重载+运算符
Vector operator+(const Vector& v1, const Vector& v2) {
    return Vector(v1.x + v2.x, v1.y + v2.y);
}

int main() {
    Vector v1(1, 2);
    Vector v2(3, 4);

    Vector v3 = v1 + v2;

    cout << "v1: ";
    v1.print();
    cout << "v2: ";
    v2.print();
    cout << "v1 + v2: ";
    v3.print();

    return 0;
}

在进行双目运算符重载时,由于友元函数不使用this指针,故其参数列表中需要将两个参数都写上,例如

friend Complex operator+(Complex& a,Complex& b); 

重载赋值运算符‘=’ 

赋值运算符重载必须作为成员函数,因为:

  • 赋值运算符需要修改左操作数的内部状态。
  • 友元函数无法访问隐式的 this 指针,也就无法直接操作对象自身的成员变量。

因此,尽管友元函数可以访问类的私有成员变量和函数,但在涉及修改对象本身的情况下(例如赋值操作),必须使用成员函数来进行重载。

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值