友元

友元函数为类

class A{
private:
    int a;
public:
    A() { a = 55; }
    friend class B;
};

class B{
private:
    int b;
public:
    void showA(A &x) {
        cout << x.a << endl;
    }
};

int main() {
    A a1;
    B b1;
    b1.showA(a1);
    return 0;
}

输出
55

友元函数为类的函数

class B;

class A
{
public:
    void showB(B& );
};

class B
{
private:
    int b;
public:
    B()  {  b = 0; }
    friend void A::showB(B& x); // Friend function
};

void A::showB(B &x)
{
    // Since show() is friend of B, it can
    // access private members of B
    std::cout << "B::b = " << x.b;
}

int main()
{
    A a;
    B x;
    a.showB(x);
    return 0;
}

输出
B::b = 0

友元函数为全局函数

class A{
private:
    int a;
public:
    A(int x) { a = x; }
    friend void showA(A &x);
};

void showA(A &x) {
    cout << x.a << endl;
}

int main()
{
    A a(44);
    showA(a);
    return 0;
}

输出
44


以下讨论继承与友元的关系:

  1. 友元函数在基函数中
class base{
protected:
    int x;
public:
    base(int a=0):x(a){}
    friend void show();
};

class base2:public base{
protected:
    int y;
public:
    base2(int b):y(b){}
};

void show() {
    base2 base_2(2);
    cout << base_2.x << endl;
    cout << base_2.y << endl;//出问题了
}

int main()
{
    show();
    return 0;
}
  1. 友元函数在继承函数中
class base{
private:
    int x1;
protected:
    int x;
public:
    base(int a=0):x(a){}
};

class base2:public base{
private:
    int y;
public:
    base2(int b):y(b){}
    friend void show();
};

void show() {
    base2 base_2(2);
    cout << base_2.x1 << endl;
    cout << base_2.x << endl;
    cout << base_2.y << endl;
}

总结:
友元函数在基函数里面a,一定可以访问基函数a的private的数据,但是不能访问继承函数B的protected的数据:
友元函数在继承函数B里面,能够访问B的private数据,同时能够访问基函数A的protected的数据,但是不能访问A的private的数据。

<think>我们正在讨论C++中的友元函数和友元类概念。根据用户的问题,需要解释这两个概念。 引用中并没有直接关于友元的内容,但我们可以根据C++知识进行解释。 注意:用户要求使用中文回答,并且按照系统级指令格式化数学表达式(如果有的话,但本题可能没有数学表达式,所以主要关注代码格式)。 另外,需要生成相关问题。 步骤: 1. 解释友元函数:友元函数是一个非成员函数,但它可以访问类的私有(private)和保护(protected)成员。 2. 解释友元类:一个类可以声明另一个类为其友元,这样友元类就可以访问该类的私有和保护成员。 3. 注意:友元关系是单向的,不具有传递性(即A是B的友元,B是C的友元,并不意味A是C的友元)。 4. 友元破坏了封装性,因此应谨慎使用。 同时,我们将按照要求生成相关问题。 由于用户的问题中要求使用中文,所以整个回答用中文。 代码部分使用代码块格式。 注意:引用标识的使用。由于我们参考了C++的一般知识,但引用中并没有直接相关的内容,因此我们可以不添加引用标识,或者如果引用中的某些内容相关(比如静态成员)可以适当提及,但友元与静态成员无关。因此,我们主要根据知识回答,不强制添加引用标识。 但是,在回答中,我们可以提到友元函数与成员函数的区别(例如,成员函数有this指针,而友元函数没有),这时可以引用[4]中提到的静态成员函数也没有this指针,但注意友元函数不是静态成员函数,它们是非成员函数。因此,我们可以对比说明。 回答结构: 1. 友元函数 2. 友元类 3. 注意事项 4. 示例代码 5. 生成相关问题 示例代码将包括一个友元函数和一个友元类的例子。</think>### C++ 友元函数与友元类详解 #### 一、核心概念 友元(friend)是 C++ 中打破封装性的特殊机制,允许**外部函数或类访问私有成员**。主要特点: 1. **单向授权**:友元关系不可传递(A 授权 B ≠ B 自动授权 A) 2. **非继承性**:友元关系不被派生类继承 3. **精准控制**:可单独声明特定函数/类为友元 4. **语法形式**:使用 `friend` 关键字声明 #### 二、友元函数 **定义**:非成员函数访问类私有数据 ```cpp class BankAccount { private: double balance; // 私有成员 friend void audit(BankAccount&); // 友元声明 }; // 友元函数实现(无需 BankAccount::) void audit(BankAccount& acc) { std::cout << "审计访问余额: " << acc.balance; // 直接访问私有成员 } ``` **典型应用场景**: - 运算符重载(如 `<<` 流操作符) ```cpp friend std::ostream& operator<<(std::ostream& os, const MyClass& obj); ``` #### 三、友元类 **定义**:整个类访问另一类的私有成员 ```cpp class Sensor { private: int rawData; // 私有数据 friend class DataProcessor; // 友元类声明 }; class DataProcessor { public: void calibrate(Sensor& s) { s.rawData += 10; // 直接访问 Sensor 的私有成员 } }; ``` **关键限制**: - 友元关系**不对称**:`DataProcessor` 可访问 `Sensor`,反之不成立 - **不继承**:`DataProcessor` 的派生类不能访问 `Sensor` 私有成员 #### 四、注意事项与最佳实践 1. **封装破坏**:过度使用会导致代码耦合(建议优先用公有接口) 2. **前置声明**:友元类需提前声明 ```cpp class DataProcessor; // 前置声明 class Sensor { friend class DataProcessor; ... }; ``` 3. **模板特化**:友元声明在类模板中需特殊处理[^2] ```cpp template<typename T> class Box { friend void inspect<T>(Box<T>&); // 模板友元 }; ``` 4. **与静态成员对比**:友元函数无 `this` 指针,静态成员函数有类作用域但无 `this` 指针[^4] #### 五、典型错误示例 ```cpp class A { friend class B; int secret; }; class B { public: void leak(A a) { std::cout << a.secret; } // 合法 }; class C : public B { public: void fail(A a) { std::cout << a.secret; // 错误!友元关系不继承 } }; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值