C++第十一篇:friend友元

C++友元机制详解

1.友元的三个特点

  • 单向性:A类中写了friend class B,说明B可以调用A中的函数,但过来不可以。
  • 不可传递性:A类中写了friend class B,B类又写了friend class C,但C类并不能调用A类中的函数。
  • 不可继承性:B类还有一个子类C,C类并不能算A类的友元,不可以调用A的函数。

2.友元函数

在 C++ 中,友元函数 是一种特殊的函数,它不属于某个类,但被允许访问该类的私有成员保护成员,打破了类的封装性限制。

友元函数可以直接访问类中的保护成员私有成员,直接看代码示例:

#include <iostream>

using namespace std;

class MyClass {
private:
    int x; 
    int y;

public:
    MyClass(int a, int b) : x(a), y(b) {}

    // 声明友元函数:该函数不是MyClass的成员,但可访问其私有成员
    friend int sum(MyClass obj); 
};

// 友元函数的实现(在类外,无需加类名和作用域运算符::)
int sum(MyClass obj) {//这里传引用更好MyClass& obj
    // 可以直接访问MyClass的私有成员x和y
    return obj.x + obj.y; 
}

int main() {
    MyClass obj(3, 5);
    cout << "sum : " << sum(obj) << endl; // 输出 sum : 8
    return 0;
}

运行结果:

示例中经过friend声明过后,sum函数就可以直接访问私有和保护成员,当然,前提是你得将对象当做参数传过来,因为友元函数不是类的成员,没有隐藏的this指针,只有通过这样才可以,使用引用更好。

3.友元成员函数

友元成员函数是指一个类的成员函数被另一个类声明为 “友元”,从而使得该成员函数能够访问另一个类的私有成员和保护成员。

代码如下:

#include <iostream>
using namespace std;

// 声明类B,因为A的成员函数需要使用B
class B;

// 定义类A
class A {
public:
    void printB(B* b);
};

// 定义类B
class B {
private:
    int num = 100;

    // 声明A的成员函数printB为B的友元
    friend void A::printB(B* b);
};

//友元函数的定义
void A::printB(B* b) {
    cout << "B的私有成员num:" << b->num << endl;
}

int main() {
    A a;
    B b;
    a.printB(&b); // 输出:B的私有成员num:100
    return 0;
}

结果:

这里和前面的类型知识将函数改为了类的成员函数,注意声明友元函数是的写法即可。

4.友元类

如果类 A 声明类 B 为友元类,那么类 B 的所有成员函数都可以访问类 A 的私有和保护(成员,无需逐个声明函数。

    看代码:

    #include <iostream>
    using namespace std;
    
    class A {
    private:
        int secret; // 私有成员
    public:
        A(int s) : secret(s) {}
    
        // 声明类B为友元类:B的所有成员函数可访问A的私有成员,
        // 但A的成员函数不能访问B的私有成员,具有单向性
        friend class B; 
    };
    
    class B {
    public:
    
        void printSecret(A& a) {
            cout << "A的私有成员:" << a.secret << endl; 
        }
    
        void modifySecret(A& a, int newVal) {
            a.secret = newVal; // 直接修改A的私有成员
        }
    };
    
    int main() {
        A a(100);
        B b;
    
        b.printSecret(a); // 输出:A的私有成员:100
        b.modifySecret(a, 200);
        b.printSecret(a); // 输出:A的私有成员:200
        return 0;
    }

    结果如下:

    这里只需要牢记友元类的特点就可以了。

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值