参考:
http://blog.csdn.net/rehongchen/article/details/7930853
http://blog.csdn.net/ming_road/article/details/6953687
http://blog.csdn.net/roden/article/details/5413371
中文版:p489 。对应英文版内容:
提示:要确定到基类的转换是否可访问,可以考虑基类的public成员是否可访问,如果可以,转换是可以访问的,否则,转换是不可访问的。
首先要明白几个概念:用户代码(user code), 后代类(subsequently derived classes),派生类(derived class)
用户代码,指的是除友元函数,成员函数之外的代码。
后代类,不仅仅指第一级派生类,还包括间接派生自基类的后续的派生类。
派生类,这里专指直接继承类。
理解了上面的概念之后,通过代码来说明c++ primer中说到的4点。
class A
{
}; class B:public A
{
public:
void fun(B&obj)
{
A obj1 = (A)obj;
}
}; class C:protected A
{
public:
void fun(C&obj)
{
A obj1 = (A)obj;
}
}; class D:private A
{
public:
void fun(D&obj)
{
A obj1 = (A)obj;
}
}; class E:public B
{
public:
void fun(B&obj)
{
A obj1 = (A)obj;
}
}; class F:public C
{
public:
void fun(C&obj)
{
A obj1 = (A)obj;
}
}; //从private继承类派生的类不能转换为基类。
class H:public D
{
public:
void fun(D&obj)
{
A obj1 = (A)obj; //error C2247: “A”不可访问,因为“D”使用“private”从“A”继承
//error C2243: “类型转换”: 从“D *”到“const A &”的转换存在,但无法访问
}
};
用户代码中访问的内容:
void inherite_test()
{
A *pb, *pc, *pe, *pd, *pf, *ph; pb = new B; //public
pc = new C; //protected error C2243: “类型转换”: 从“C *”到“A *”的转换存在,但无法访问
pd = new D; //private error C2243: “类型转换”: 从“D *”到“A *”的转换存在,但无法访问
pe = new E; //public + public
pf = new F; //protected + public error C2243: “类型转换”: 从“F *”到“A *”的转换存在,但无法访问
ph = new H; //private + public error C2243: “类型转换”: 从“H *”到“A *”的转换存在,但无法访问
}
解析:
其中类B,C,D分别通过public,protected,private直接继承自A; 类E,F,H则分别public继承自B,C,D类。
各类的成员函数fun中进行派生类到基类的转换操作。
1、pb = new B; B::fun,E::fun函数说明:
如果是public继承,则用户代码和后代类都可以使用派生类到基类的转换。
If the inheritance is public, then both user code and member functions of subsequently derived classes may use the derived-to-base conversion
2、inherite_test中C,D,F,H类转换的失败都说明了:
如果类是使用private或protected继承派生的,则用户代码不能将派生类型对象转换为基类对象。
If a class is derived using private or protected inheritance, then user code may not convert an object of derived type to a base type object.
3、H类的fun函数发生的错误显示:
从private继承类派生的类不能转换为基类。
If the inheritance is private, then classes derived from the privately inherited class may not convert to the base class.
4、C::fun函数说明:
如果是protected继承,则后续派生类的成员可以转换为基类类型。
If the inheritance is protected, then the members of subsequently derived classes may convert to the base type.
有一点需要说明:对于多级派生的,要多个访问标号综合起来看可访问性。 有个简单的方法,见上面的tips.
例如,C 类protected继承自A,那么A中的public成员在C中变成了protected, F类public继承自C,这样在F中A的public成员fun函数为protected,是可见的。
所以F::fun中派生类到基类转换正确。
但是在用户代码中,是不能访问在C,F中变成了protected的A的public成员的,因此C,F对象转换为类A的对象出错。
=====>感觉fun函数定义的有点不合适,挺奇怪的,但是编译是没问题的,不知道现实生产中有没有这么用的??? (待定)