【C++】友元类

在这里插入图片描述

上期回顾: 【C++】IO流
个人主页:C_GUIQU
归属专栏:C++

在这里插入图片描述

正文

1. 友元类概述

在 C++ 中,友元类(Friend Class) 是指允许其他类访问它的私有成员和保护成员的类。友元类并不继承或派生自另一个类,它通过 friend 关键字声明,使得指定的类能够访问另一个类的私有或受保护的数据成员和成员函数。

友元类的用途:

  • 打破封装性:友元类允许不同的类直接共享数据,可以让一些类能够直接操作其他类的私有数据。
  • 简化代码:在某些场合,友元类可以减少接口的复杂度,使得类之间的操作更直接、高效。
  • 实现复杂操作:如重载运算符等功能时,友元类可以访问并修改私有成员,提供更灵活的操作。

2. 友元类的语法

在 C++ 中声明友元类非常简单,使用 friend 关键字即可声明其他类为友元类。

2.1 基本语法

class ClassB;  // 前向声明

class ClassA {
    friend class ClassB;  // 将 ClassB 声明为 ClassA 的友元类
private:
    int data;
public:
    ClassA() : data(0) {}
};

class ClassB {
public:
    void showData(ClassA &a) {
        // 可以直接访问 ClassA 的私有成员
        std::cout << "ClassA's private data: " << a.data << std::endl;
    }
};

在上面的例子中,ClassB 被声明为 ClassA 的友元类,因此 ClassB 可以访问 ClassA 的私有成员 data

2.2 友元类的访问权限

  • 友元类可以访问另一个类的所有私有成员和保护成员。
  • 友元类并不是类的成员,它们只是被授予了访问权限。

3. 友元类的使用示例

基本示例:

在下面的代码示例中,BoxPrinterBox 类的友元类,能够直接访问 Box 类的私有数据。

#include <iostream>
using namespace std;

class Box {
    friend class BoxPrinter;  // 声明 BoxPrinter 为 Box 的友元类
private:
    double length;
public:
    Box(double l) : length(l) {}
};

class BoxPrinter {
public:
    void printLength(Box &b) {
        // 直接访问 Box 类的私有成员
        cout << "Box length: " << b.length << endl;
    }
};

int main() {
    Box b(10.5);       // 创建 Box 对象
    BoxPrinter bp;     // 创建 BoxPrinter 对象
    bp.printLength(b); // 使用友元类访问 Box 的私有成员
    return 0;
}

输出:

Box length: 10.5

在这个例子中,BoxPrinterBox 的友元类,它通过 printLength 方法能够访问 Box 类的私有成员 length


4. 友元类与封装性

虽然友元类可以让一个类访问另一个类的私有成员,但这种做法破坏了封装性,可能会导致代码变得不易维护。因此,应该谨慎使用友元类。

4.1 友元类的优势

  • 简化类间协作:友元类提供了直接访问另一个类私有数据的方式,从而简化了类与类之间的交互。
  • 减少接口复杂性:通过友元类,可以避免暴露过多的 getter 和 setter 函数,简化接口设计。

4.2 友元类的缺点

  • 破坏封装性:友元类会使类的私有成员暴露给其他类,可能导致不易控制的数据访问,降低系统的安全性和可维护性。
  • 增加依赖性:类之间的紧密依赖可能增加代码的复杂度,导致模块间耦合度过高,影响系统的可扩展性。

5. 友元类的进阶应用

友元类不仅可以用于简单的数据共享,也常用于操作符重载、模板类等更复杂的场景。

友元类与运算符重载:

在运算符重载中,友元类的使用非常常见,特别是当需要直接访问类的私有成员时。

#include <iostream>
using namespace std;

class Complex {
    friend Complex operator+(const Complex &c1, const Complex &c2);  // 声明友元函数
private:
    int real, imag;
public:
    Complex(int r, int i) : real(r), imag(i) {}
    void print() {
        cout << real << " + " << imag << "i" << endl;
    }
};

Complex operator+(const Complex &c1, const Complex &c2) {
    // 通过友元函数访问私有成员
    return Complex(c1.real + c2.real, c1.imag + c2.imag);
}

int main() {
    Complex c1(3, 4), c2(1, 2);
    Complex c3 = c1 + c2;
    c3.print();  // 输出结果: 4 + 6i
    return 0;
}

输出:

4 + 6i

在这个示例中,operator+ 是一个友元函数,它可以直接访问 Complex 类的私有成员 realimag,实现了复数相加的操作。


6. 结论

友元类在 C++ 中提供了一种特殊的访问权限,使得不同类之间可以直接共享私有数据。然而,使用友元类时必须小心,避免破坏类的封装性。通常情况下,只有在类之间需要紧密协作时,才推荐使用友元类。

  • 友元类提供了高效、灵活的类间协作方式。
  • 友元类可能增加代码的复杂度,降低可维护性,因此使用时需要谨慎。
  • 在设计良好的系统中,尽量避免过多使用友元类。

结语
感谢您的阅读!期待您的一键三连!欢迎指正!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Guiat

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值