然而通过实践发现,VS编译器并没有安装上述描述来处理,下面的规则与上述描述相悖,却符合VS编译器的处理规则。
1 友元类的继承问题
1.1一个友元类的派生类,可以通过其基类接口去访问设置其基类为友元类的类的私有成员,也就是说一个类的友元类的派生类,某种意义上还是其友元类,这句话有点绕,上代码就清晰了
示例代码:
[cpp] view plain copy
#include <iostream>
using namespace std;
class B;
class A
{
int a;
public:
A(int x=0) { a=x; }
friend class B;
};
class B
{
int b;
public:
void fun(A& ob){ cout << ob.a << endl;}
};
class C:public B
{
public:
//void fun2(A& ob){ cout <<ob.a <<endl;} //派生类新加的函数却不能访问A,此句会报错
};
void main()
{
A a(55);
C c;
c.fun(a); //C是B的派生类 通过基类B的函数fun仍然可以访问
}
1.2.一个派生类的基类的友元类仍然是它的友元类
示例代码如下:
[cpp] view plain copy
#include <iostream>
using namespace std;
class B;
class A
{
int a;
public:
A(int x=0){ a=x; }
friend class B;
};
class C:public A //通过继承,A的友员类B成了派生类C的友员类
{
public:
C(int x):A(x){}
};
class B
{
public:
void fun(A& ob) { cout <<ob.a << endl; }
void fun2(C& ob) { cout << ob.a << endl; }
};
void main()
{
C c(55);
B b;
b.fun(c);
b.fun2(c);
}
2 友元函数的继承问题
基类的友元函数仍然是派生类的友元函数
示例代码:
[cpp] view plain copy
#include <iostream>
using namespace std;
class B;
class A
{
int a;
public:
A(int x=0) { a=x; }
friend void fun(B&); //若注释掉此句则无法通过编译
virtual ~A(){} //用作基类的类皆添加一个虚析构函数是一个好习惯,无论析构函数是否真的需要
};
class B: public A
{
public:
B(int x): A(x) {}
};
void fun(B& o)
{
cout << o.a << endl;
}
void main()
{
//A a(55);
B b(66);
//fun(a);
fun(b);
}
3 友元类的传递问题
一个友元类B的友元类,对将B设置为友元类的类没有特殊的访问权限
示例代码如下:
[cpp] view plain copy
#include <iostream>
using namespace std;
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()
{ }
4 友元函数的传递问题
一个友元类的友元函数对设置这个类为友元类的类没有特殊访问权限
示例代码如下:
[cpp] view plain copy
#include <iostream>
using namespace std;
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 void fun2(A& ob);
};
void fun2(A& ob)
{ cout << ob.a << endl; //此句无法通过编译
}
void main()
{ }
5. Base的友元可以通过Base的派生类Drived访问Base的private,protect成员变量,但不能访问Drived的private,protect成员变量。(这一点似乎与《C++ primer》里说的有点冲突)
个人理解:Drived的对象本身就包含Base,Base的友元Frnd自然就可以访问Base的部分。
#include <iostream>
using namespace std;
class Base
{
int m_a;
public:
Base(int x=0){ m_a=x; }
friend class Frnd;
};
class Drived:public Base
{
private:
int m_c;
public:
Drived(int x):Base(x){m_c=x;}
};
class Frnd
{
public:
void fun(Base& ob) { cout <<ob.m_a << endl; }
void fun2(Drived& ob)
{
cout << ob.m_a<<endl;
//cout <<ob.m_c<<endl; //编译错误
}
};
int main()
{
Drived d(1);
Frnd f;
f.fun(d);
f.fun2(d);
system("pause");
return 0;
}
6.友元类的传递问题
A的友元是B,B的友元是C,那A的友元是C? 不是,友元类不具有传递性。
http://blog.csdn.net/yucan1001/article/details/6926087
http://blog.csdn.net/shandianling/article/details/7469361