C++一个类的成员函数作为另一个类的友元函数

本文详细介绍了C++中友元函数的概念及其使用场景,通过实例代码展示了如何利用友元函数访问私有成员,解释了类声明顺序对友元函数有效性的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先上一段代码。定义了两个类,都有私有变量num。分别用全局函数、友元函数计算两者的和。

#include<iostream>  
using namespace std;  
  
class B;
class A;	// 此行可不加,这里加此行是因为下面举例子有用  
class A {  
public:  
    A(int n = 0): num(n) {} // 构造函数  
    friend void sum_1(A &a, B &b);  // 全局函数 sum_1  
    void sum_2(B &b);               // 成员函数 sum_2  
private:  
    int num;  
};  
  
class B {  
public:  
    B(int n = 0) : num(n) {}    // 构造函数  
    friend void sum_1(A &a, B &b);  // 全局函数 sum_1  
    friend void A::sum_2(B &b);     // 友元函数 A::sum_2  
private:  
    int num;  
};  
// 全局函数  
void sum_1(A &a, B &b) {  
    int sum = a.num + b.num;    // 访问了两个对象的私有变量  
    cout << a.num << " + " << b.num << " = " << sum << endl;  
}  
// 友元函数  
void A::sum_2(B &b) {  
    int sum = num + b.num;  // 访问了参数对象的私有变量  
    cout << num << " + " << b.num << " = " << sum << endl;  
}  
  
int main() {  
    A a(1);  
    B b;  
    sum_1(a, b);  	// 调用全局函数
    a.sum_2(b);  	// 调用a的成员函数
    system("PAUSE");  
    return 0;  
}  

1. 提前声明要使用的类

若注释掉此行

class B;

编译器会报错:error C2061: 语法错误: 标识符“B”

本例中,先对类 B 进行了声明,但是没有定义。因为在类 A 的定义中,出现的函数 sum_1 和 sum_2 均要用到类B 名,所以必须事先声明“B”是一个类名,这样编译器才不会因为不知道”B“是什么而报错。

2. 必须将先定义的类的成员函数作为后定义类的友元函数,调换顺序会出现语法错误

本例中,若将 A、B 类的定义顺序调换,其余均不变,则出现语法错误

#include<iostream>  
using namespace std;  
  
class B;
class A;	// 此行可不加,这里加此行是因为下面举例子有用 
class B {  	// A、B类的定义顺序变了
.../*中间的语句不变*/   
}; 
class A {  
.../*中间的语句不变*/  
};  
  
.../*后面的语句不变*/

在友元函数的实现中,会出现在这里插入图片描述
这说明B类中没有成功的把A类的成员函数sum_2声明为自己的友元函数。
道理很很简单,和第1点很相似。若先定义B类,那么我们观察一下B类定义中的如下语句

friend void A::sum_2(B &b);		// 友元函数 A::sum_2

该语句通过类名加域运算符,将A类的成员函数sum_2声明为友元函数。等等,是不是发现了什么,这是A类根本还没有定义,编译器只知道A是一个类名,A中具体有什么全然不知。如此,那么这一个语句当然无效咯!

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值