派生类到基类转换到可访问性

本文详细探讨了C++中不同类型的继承(public、protected 和 private)如何影响派生类到基类的转换。通过实例展示了在各种继承情况下,派生类能否成功转换为基类,并解释了转换是否可访问的判断依据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


要确定到基类的转换是否可访问,可以考虑基类的public成员是否可访问,如果可以,转换是可以访问的,否则,转换是不可访问的。

  • 如果是public继承,则用户代码和后代类都可以使用派生类到基类的转换。
  • 如果类是使用private或protected继承派生的,则用户代码不能将派生类型对象转换为基类对象。
  • 如果是private继承,则从private继承类派生的类不能转换为基类。
  • 如果是protected继承,则后续派生类的成员可以转换为基类类型。
无论是什么派生访问标号,派生类本身都可以访问基类的public成员,因此,派生类本身的成员和友元总是可以访问派生类到基类的转换。

Like an inherited member function, the conversion from derived to base may or may not be accessible. Whether the conversion is accessible depends on the access label specified on the derived class' derivation.

If the inheritance is public, then both user code and member functions of subsequently derived classes may use the derived-to-base conversion. 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. If the inheritance is private, then classes derived from the privately inherited class may not convert to the base class. If the inheritance is protected, then the members of subsequently derived classes may convert to the base type.

Regardless of the derivation access label, a public member of the base class is accessible to the derived class itself. Therefore, the derived-to-base conversion is always accessible to the members and friends of the derived class itself.

Tips:To determine whether the conversion to base is accessible, consider whether a public member of the base class would be accessible. If so, the conversion is accessible; otherwise, it is not.

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 *”的转换存在,但无法访问
}

解析:


首先要明白几个概念:用户代码(user code), 后代类(subsequently derived classes),派生类(derived class)

  • 用户代码,指的是除友元函数,成员函数之外的代码。
  • 后代类,不仅仅指第一级派生类,还包括间接派生自基类的后续的派生类。
  • 派生类,这里专指直接继承类。


其中类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、F::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的对象出错。


参考:

http://blog.youkuaiyun.com/shanki_pm/article/details/6534222

http://www.cnblogs.com/qingxinlangjing/p/3214472.html

http://blog.youkuaiyun.com/geekwangminli/article/details/7930853




 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值