声明:①友元关系不能被继承和传递,基类的友元对派生类没有特殊的访问权限,派生类中的友元更不能访问基类中的成员。
②友元不是成员函数,所以不能使用作用域解析符来指出要使用哪个函数。这个问题的解决方法是使用强制类型转换,以便匹配原型时能够选择正确地函数。
③基类的友元能够访问派生类中的基类成分,这是由于自动将派生类转化成了基类,不是因为继承,但是不能访问派生类的非基类成员。
下面通过例子对这几个问题一一说明。
#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