【问题标题】:Does protected inheritance allow the derived class access the private members of its base class?受保护的继承是否允许派生类访问其基类的私有成员?
【发布时间】:2010-01-28 18:31:01
【问题描述】:

我真的对私有继承和受保护继承感到困惑。

1) 在受保护的继承中,公共成员和受保护成员成为派生类中的受保护成员。在私有继承中,一切都是私有的。但是,派生类永远不能访问基类的私有成员,对吗?在这两种情况下,派生类都可以访问公共成员和受保护成员。那正确吗?

2) 我注意到基类的私有成员永远不会被派生类触及。那么为什么私有成员会被继承呢?

【问题讨论】:

    标签: c++


    【解决方案1】:

    您在第 1 点上是正确的。从基类继承时指定privateprotectedpublic 不会更改派生类本身的任何访问方式。当派生类的实例在别处使用时,或者派生类碰巧用作其他类的基类时,这些访问说明符告诉编译器如何处理基类成员。

    更新:以下内容可能有助于说明差异:

    class Base
    {
        private:   int base_pri;
        protected: int base_pro;
        public:    int base_pub;
    };
    

    对于从基类派生的类:

    class With_Private_Base :   private Base   { void memberFn(); };
    class With_Protected_Base : protected Base { void memberFn(); };
    class With_Public_Base :    public Base    { void memberFn(); };
    
    // this would be the same for all of the above 3 classes:
    void With_PXXX_Base::memberFn()
    {
        base_pri = 1; // error: `int Base::base_pri' is private
        base_pro = 1; // OK
        base_pub = 1; // OK
    }
    

    对于从 3 个派生类派生的类:

    class A : public With_Private_Base { void memberFn(); }
    void A::memberFn()
    {
        base_pri = 1; // error: `int Base::base_pri' is private
        base_pro = 1; // error: `int Base::base_pro' is protected
        base_pub = 1; // error: `int Base::base_pub' is inaccessible
    }
    
    class B : public With_Protected_Base { void memberFn(); }
    void B::memberFn()
    {
        base_pri = 1; // error: `int Base::base_pri' is private
        base_pro = 1; // OK
        base_pub = 1; // OK
    }
    
    class C : public With_Public_Base { void memberFn(); }
    void C::memberFn()
    {
        base_pri = 1; // error: `int Base::base_pri' is private
        base_pro = 1; // OK
        base_pub = 1; // OK
    }
    

    对前三个派生类的外部访问:

    void main()
    {
        With_Private_Base   pri_base;
        pri_base.base_pri = 1; // error: `int Base::base_pri' is private
        pri_base.base_pro = 1; // error: `int Base::base_pro' is protected
        pri_base.base_pub = 1; // error: `int Base::base_pub' is inaccessible
    
        With_Protected_Base pro_base;
        pro_base.base_pri = 1; // error: `int Base::base_pri' is private
        pro_base.base_pro = 1; // error: `int Base::base_pro' is protected
        pro_base.base_pub = 1; // error: `int Base::base_pub' is inaccessible
    
        With_Public_Base    pub_base;
        pub_base.base_pri = 1; // error: `int Base::base_pri' is private
        pub_base.base_pro = 1; // error: `int Base::base_pro' is protected
        pub_base.base_pub = 1; // OK
    }
    

    【讨论】:

    • 受保护的继承和公共的继承是一样的吗?
    • @fahad:从派生类的角度来看,是的。从外部访问的角度来看(我回答中的最后一段代码),它们完全不同。
    【解决方案2】:

    1a) 受保护的继承意味着“子”可以访问它在公共继承中可以访问的所有内容,但使用该对象的其他人只能看到子的公共接口,其父级中的任何内容都被隐藏。

    1b) 私有继承导致类的所有公共函数都被继承为私有函数 - 这意味着它们不能从子对象调用或从对象的客户端访问。

    2) 私有成员被继承,因为基类中的方法可能需要它们来操作。

    【讨论】:

      【解决方案3】:
      1. 是的,这是正确的。派生类可以访问其基类的受保护成员和公共成员,而派生类不能访问其基类的私有成员。

      2. 私有成员被继承的原因如下:基类可以定义一个受保护的或公共的函数来修改基类的私有成员。派生类可以调用这个函数,因此需要知道它正在访问的私有变量。

      【讨论】:

        【解决方案4】:

        1) 在受保护的继承中, 公共和受保护成员成为 派生中的受保护成员 班级。在私人继承中, 一切都是私人的。但是,那 派生类永远无法访问 基类的私有成员,是 对吗?

        是的。

        派生类可以 访问公众并受保护 两种情况下的成员。对吗?

        是的。

        2) 我注意到私人成员 基类的永远不会 被派生类触及。所以为什么 私有成员是否继承?

        因为它们是基类的一部分,而您需要作为派生类一部分的基类。请注意,您仍然可以使用非重写的public/protected 成员函数来操作在基类中维护的某些状态(如果有)。

        【讨论】:

          【解决方案5】:

          1) 你是对的。没有任何类型的继承允许访问私有成员(只有 friend 声明允许)

          2) 从某种意义上说,它们是“继承的”,即 Derived 类型的对象在存储在内存中时,包括 Derived 和 Base 的所有数据成员,包括 Base 的私有成员。私有成员不能消失,因为当 Base 的方法在该对象上运行时,它们将需要访问 Base 的私有成员。

          此外,从技术上讲,Base 的私有成员的名称在 Derived 方法的范围内,但是如果您尝试访问它们当然会出现编译错误。

          【讨论】:

            猜你喜欢
            • 2012-05-03
            • 2018-10-21
            • 2019-01-20
            • 2014-08-27
            • 1970-01-01
            • 2016-07-15
            • 2012-08-29
            • 1970-01-01
            • 2014-11-27
            相关资源
            最近更新 更多