先上一段代码。定义了两个类,都有私有变量num。分别用全局函数、友元函数计算两者的和。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 
 | #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);
 void sum_2(B &b);
 private:
 int num;
 };
 
 class B {
 public:
 B(int n = 0) : num(n) {}
 friend void sum_1(A &a, B &b);
 friend void A::sum_2(B &b);
 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);
 system("PAUSE");
 return 0;
 }
 
 | 
1. 提前声明要使用的类
编译器会报错:error C2061: 语法错误: 标识符“B”
本例中,先对类 B 进行了声明,但是没有定义。因为在类 A 的定义中,出现的函数 sum_1 和 sum_2 均要用到类B 名,所以必须事先声明“B”是一个类名,这样编译器才不会因为不知道”B“是什么而报错。
2. 必须将先定义的类的成员函数作为后定义类的友元函数,调换顺序会出现语法错误
本例中,若将 A、B 类的定义顺序调换,其余均不变,则出现语法错误
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | #include<iostream>  using namespace std;
 
 class B;
 class A;
 class B {
 ...
 };
 class A {
 ...
 };
 ...
 
 | 
在友元函数的实现中,会出现

这说明B类中没有成功的把A类的成员函数sum_2声明为自己的友元函数。 道理很很简单,和第1点很相似。若先定义B类,那么我们观察一下B类定义中的如下语句
| 1
 | friend void A::sum_2(B &b);     
 | 
该语句通过类名加域运算符,将A类的成员函数sum_2声明为友元函数。等等,是不是发现了什么,这是A类根本还没有定义,编译器只知道A是一个类名,A中具体有什么全然不知。如此,那么这一个语句当然无效咯!
likeqc
ends