先上一段代码。定义了两个类,都有私有变量num。分别用全局函数、友元函数计算两者的和。
1 2 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 类的定义顺序调换,其余均不变,则出现语法错误
1 2 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