声明:①友元关系不能被继承和传递,基类的友元对派生类没有特殊的访问权限,派生类中的友元更不能访问基类中的成员。
②友元不是成员函数,所以不能使用作用域解析符来指出要使用哪个函数。这个问题的解决方法是使用强制类型转换,以便匹配原型时能够选择正确地函数。
③基类的友元能够访问派生类中的基类成分,这是由于自动将派生类转化成了基类,不是因为继承,但是不能访问派生类的非基类成员。
下面通过例子对这几个问题一一说明。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> using namespace std; class baseDMA; class hasDMA; ostream& operator<<(ostream& os,const baseDMA& rs); ostream& operator<<(ostream& os,const hasDMA& rs); void fun(const hasDMA& hr); class baseDMA { friend ostream& operator<<(ostream& os,const baseDMA& rs); friend void fun(const hasDMA& hr); public: baseDMA(const char* l="null",int r=0) { label = new char[strlen(l)+1]; strcpy(label,l); rating = r; } virtual ~baseDMA() { delete [] label; } private: char* label; int rating; }; class hasDMA:public baseDMA { friend ostream& operator<<(ostream& os,const hasDMA& rs); public: hasDMA(const char* s="none",const char* l="null",int r=0) :baseDMA(l,r) { style = new char[strlen(s)+1]; strcpy(style,s); } ~hasDMA() { delete [] style; } private: char* style; }; ostream& operator<<(ostream& os,const baseDMA& rs) { os << "Label: " << rs.label << endl; os << "Rating: " << rs.rating << endl; return os; } ostream& operator<<(ostream& os,const hasDMA& rs) { //os << "Label: " << rs.label << endl;//(一) //os << "Rating: " << rs.rating << endl;//(二) os << (const baseDMA&)rs;//(三) os << "Style: " << rs.style << endl; return os; } void fun(const hasDMA& hr) { //cout << hr.style << endl;//(四) cout << hr.label << endl;//(五) } class A { int a; public: A(int x=0) { a=x; } friend class B; }; class B { public: void fun(A& ob) { cout << ob.a << endl; } friend class C; }; class C { public: //void fun(A& ob) { cout << ob.a << endl; } (六) }; void main( void ) { baseDMA shirt("port",8); hasDMA map("mer","buf",5); cout << shirt << endl; cout << map << endl; }
由(一)和(二)两条语句可知,派生类中的友元是不能访问基类中的成员的。
由语句(三)可知我们有一种方法,就是通过强制类型转换将派生类转换成基类,然后使用基类中的友元函数。
由语句(四)和(五)可知,基类中的友元不能访问派生类中的非基类成员,但是能访问派生类中的基类成员,这是通过自动将派生类转化成基类来实现的。
由(六)可知,友元不具有传递性,B是A的友元,C是B的友元,不能得到C是A的友元,所以C不能访问A中的数据。
我在这里所说的友元既包括友元类,也包括友元函数,在继承和传递的问题上两者是保持一致的。
原文地址:http://blog.csdn.net/fayery/article/details/26735237