C++ 私有继承、公共继承和受保护继承之间的区别

C++ 私有继承、公共继承和受保护继承之间的区别,c++,inheritance,encapsulation,access-specifier,c++-faq,C++,Inheritance,Encapsulation,Access Specifier,C++ Faq,在C++中,public、private和protected继承之间有什么区别? 我在上面找到的所有问题都是针对特定情况的。这与基类的公共成员如何从派生类中公开有关 public->基类的public成员将是public(通常为默认值) 受保护->基类的公共成员将受到保护 私有->基类的公共成员将是私有的 正如litb所指出的,公共继承是在大多数编程语言中都会看到的传统继承。也就是说,它模拟了一种“是一种”关系。私有继承,是C++特有的东西,是一种“以关系实现”的关系。也就是说,您希望使用派

C++中,
public
private
protected
继承之间有什么区别?


我在上面找到的所有问题都是针对特定情况的。

这与基类的公共成员如何从派生类中公开有关

  • public->基类的public成员将是public(通常为默认值)
  • 受保护->基类的公共成员将受到保护
  • 私有->基类的公共成员将是私有的

正如litb所指出的,公共继承是在大多数编程语言中都会看到的传统继承。也就是说,它模拟了一种“是一种”关系。私有继承,是C++特有的东西,是一种“以关系实现”的关系。也就是说,您希望使用派生类中的公共接口,但不希望派生类的用户能够访问该接口。许多人认为,在这种情况下,您应该聚合基类,而不是将基类作为私有基类,使其成为派生类的成员,以便重用基类的功能。

这与如何从派生类公开基类的公共成员有关

  • public->基类的public成员将是public(通常为默认值)
  • 受保护->基类的公共成员将受到保护
  • 私有->基类的公共成员将是私有的

正如litb所指出的,公共继承是在大多数编程语言中都会看到的传统继承。也就是说,它模拟了一种“是一种”关系。私有继承,是C++特有的东西,是一种“以关系实现”的关系。也就是说,您希望使用派生类中的公共接口,但不希望派生类的用户能够访问该接口。许多人认为,在这种情况下,您应该聚合基类,而不是将基类作为私有基类,使其成为派生的成员,以便重用基类的功能。

为了回答这个问题,我想先用我自己的话来描述成员的访问器。如果您已经知道这一点,请跳到标题“下一步:”

我知道有三种访问器:
public
protected
private

让我们:

  • 所有知道
    Base
    的东西也知道
    Base
    包含
    publicMember
  • 只有子级(及其子级)知道
    Base
    包含
    protectedMember
  • 只有
    Base
    知道
    privatember
所谓“意识到”,我的意思是“承认存在,从而能够访问”

下一步: 公共继承、私有继承和受保护继承也是如此。让我们考虑一个类<代码> Base<代码>和一个类<代码>子<代码>,继承自<代码> Base< /Cord>
  • 如果继承是
    public
    ,那么所有知道
    Base
    Child
    的东西也知道
    Child
    继承自
    Base
  • 如果继承受
    保护
    ,则只有
    子项
    及其子项知道它们是从
    基继承的
  • 如果继承是
    私有的
    ,则除了
    子继承
    之外,没有人知道该继承

    • 为了回答这个问题,我想先用我自己的话描述一下会员的访问者。如果您已经知道这一点,请跳到标题“下一步:”

      我知道有三种访问器:
      public
      protected
      private

      让我们:

      • 所有知道
        Base
        的东西也知道
        Base
        包含
        publicMember
      • 只有子级(及其子级)知道
        Base
        包含
        protectedMember
      • 只有
        Base
        知道
        privatember
      所谓“意识到”,我的意思是“承认存在,从而能够访问”

      下一步: 公共继承、私有继承和受保护继承也是如此。让我们考虑一个类<代码> Base<代码>和一个类<代码>子<代码>,继承自<代码> Base< /Cord>
      • 如果继承是
        public
        ,那么所有知道
        Base
        Child
        的东西也知道
        Child
        继承自
        Base
      • 如果继承受
        保护
        ,则只有
        子项
        及其子项知道它们是从
        基继承的
      • 如果继承是
        私有的
        ,则除了
        子继承
        之外,没有人知道该继承

      它本质上是对派生类中的公共和受保护基类成员的访问保护。通过公共继承,派生类可以看到基类的公共成员和受保护成员。对于私有继承,它不能。使用protected,派生类和从中派生的任何类都可以看到它们。

      它本质上是对派生类中基类的公共成员和受保护成员的访问保护。通过公共继承,派生类可以看到基类的公共成员和受保护成员。对于私有继承,它不能。使用protected,派生类和从中派生的任何类都可以看到它们。

      从类继承的任何类都可以访问受保护的数据成员。但是,私有数据成员不能。假设我们有以下几点:

      class MyClass {
          private:
              int myPrivateMember;    // lol
          protected:
              int myProtectedMember;
      };
      
      在此类的扩展中,引用
      this.myPrivateMember
      将不起作用。但是,
      this.myProtectedMember
      。值仍然被封装,因此如果我们有一个名为class MyClass { private: int myPrivateMember; // lol protected: int myProtectedMember; };
      class A 
      {
          public:
             int x;
          protected:
             int y;
          private:
             int z;
      };
      
      class B : public A
      {
          // x is public
          // y is protected
          // z is not accessible from B
      };
      
      class C : protected A
      {
          // x is protected
          // y is protected
          // z is not accessible from C
      };
      
      class D : private A    // 'private' is default for classes
      {
          // x is private
          // y is private
          // z is not accessible from D
      };
      
      class B {};
      class D : public B {};
      
      class B {};
      class D : private B {};
      
      class B {};
      class D {
        private: 
          B b_;
      };
      
      class button : public window { };
      
      struct empty_pair_impl : protected empty_class_1 
      { non_empty_class_2 second; };
      
      struct pair : private empty_pair_impl {
        non_empty_class_2 &second() {
          return this->second;
        }
      
        empty_class_1 &first() {
          return *this; // notice we return *this!
        }
      };
      
      template<typename StorageModel>
      struct string : private StorageModel {
      public:
        void realloc() {
          // uses inherited function
          StorageModel::realloc();
        }
      };
      
      class pair {
      public:
        First first;
        Second second;
      };
      
      class window {
      public:
          int getWidth() const;
      };
      
      class stack {
      protected:
        vector<element> c;
      };
      
      class window {
      protected:
        void registerClass(window_descriptor w);
      };
      
      class window {
      private:
        int width;
      };
      
      Member in base class : Private   Protected   Public   
      
      Private            :   Inaccessible   Private     Private   
      Protected          :   Inaccessible   Protected   Protected  
      Public             :   Inaccessible   Protected   Public
      
      class Base
      {
      public:
          int m_nPublic; // can be accessed by anybody
      private:
          int m_nPrivate; // can only be accessed by Base member functions (but not derived classes)
      protected:
          int m_nProtected; // can be accessed by Base member functions, or derived classes.
      };
      
      class Derived: public Base
      {
      public:
          Derived()
          {
              // Derived's access to Base members is not influenced by the type of inheritance used,
              // so the following is always true:
      
              m_nPublic = 1; // allowed: can access public base members from derived class
              m_nPrivate = 2; // not allowed: can not access private base members from derived class
              m_nProtected = 3; // allowed: can access protected base members from derived class
          }
      };
      
      int main()
      {
          Base cBase;
          cBase.m_nPublic = 1; // allowed: can access public members from outside class
          cBase.m_nPrivate = 2; // not allowed: can not access private members from outside class
          cBase.m_nProtected = 3; // not allowed: can not access protected members from outside class
      }
      
      Accessors    | Base Class | Derived Class | World
      —————————————+————————————+———————————————+———————
      public       |      y     |       y       |   y
      —————————————+————————————+———————————————+———————
      protected    |      y     |       y       |   n
      —————————————+————————————+———————————————+———————
      private      |            |               |    
        or         |      y     |       n       |   n
      no accessor  |            |               |
      
      y: accessible
      n: not accessible