今天下了OpenNurbs(www.opennurbs.org)的最新代码Build了一下,竟然没编译失败, 而且还是语法错误, 心想这堂堂一个优秀开源库的官方网站上下的代码, 竟然有如此低级的错误, 不由的一声冷笑(不敢多笑,这OpenNurbs可是编程与数学的完美组合, 不是一般人能写出来的)。然后看到几个编译错误都是关于友元访问的, 就想把它改改好就行了, 想不到左改右改, 竟然没搞定, 谁是谁的朋友,谁能访问谁,有脑一片混乱。。。。。 没办法, 乖乖的拿出<<The C++ Programming Language>> 查了起来。
其实C++中友元的规定还是很形象的,假设a要知道b的秘密(private),那么b必须要接受a, 认定a是他的朋友;但是至于a当不当b是朋友, 那就不一定了(怎么可以这样呢:)). 那么在C++中就是如果在b中声明了a为其友元,a就能访问b的私有成员, 但是同时,b还不能访问a的私有成员(因为没有在a中声明b为其友元)。如下:二
class b
{
friend class a;
public:
b(){};
void bf1(){}
protected:
void bf2(){}
private:
void bf3(){}
};
class a
{
public:
a(){b bb;bb.bf1();bb.bf2();bb.bf3();}
void af1(){b bb;bb.bf1();bb.bf2();bb.bf3();}
protected:
void af2(){b bb;bb.bf1();bb.bf2();bb.bf3();}
private:
void af3(){b bb;bb.bf1();bb.bf2();bb.bf3();}
};
当我声明a为b的友元类后, a中的所有类型的函数(public, protected, private)都可以访问b中的任何类型的成员了(public, protected, private).
对于函数, 也是同样的道理,假如函数要访问b中的私有成员, 就要把该函数声明成b的友元:
class b
{
friend void f1();
public:
b(){};
void bf1(){}
protected:
void bf2(){}
private:
void bf3(){}
};
void f1()
{
b bb;
bb.bf1();
bb.bf2();
bb.bf3();
}
函数f1()作为类b的友元, 就有权力访问b的任何成员。当然, 对于成员函数作为友元, 也是一样的做法。
这里我总结出一条: 谁要访问其它类的保护或私有成员, 它就要成为那个类的友元, 在那个类里面声明。 这里这个“谁”可以是一个类, 一个全局函数, 或者一个类的成员函数。
注:
今天在测试时竟然发现可以这现声明成员函数:
class b
{
public:
b::b(){};
void b::bf1(){}
};
也就是在成员函数前又加了一次类域, 至少在VC++8可以通过编译, 以前还真没发现。