协慌网

登录 贡献 社区

私有,公共和受保护继承之间的区别

C ++ 中的publicprivateprotected继承有什么区别?我在 SO 上发现的所有问题都涉及具体案例。

答案

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
};

重要说明:B,C 和 D 类都包含变量 x,y 和 z。这只是访问问题。

关于受保护和私有继承的使用,您可以在这里阅读。

要回答这个问题,我想先用自己的话来描述成员的访问者。如果您已经知道这一点,请跳至标题 “next:”。

我知道有三种访问者: publicprotectedprivate

让:

class Base {
    public:
        int publicMember;
    protected:
        int protectedMember;
    private:
        int privateMember;
};
  • 知道Base所有内容都知道Base包含publicMember
  • 只有子项(及其子项)知道Base包含protectedMember
  • 除了Base没有人知道privateMember

通过 “意识到”,我的意思是 “承认存在,从而能够访问”。

下一个:

公共,私有和受保护的继承也是如此。让我们考虑一个类Base和一个继承自Base的类Child

  • 如果继承是public ,那么知道BaseChild内容也都知道Child继承自Base
  • 如果继承protected ,则只有Child及其子代知道它们从Base继承。
  • 如果继承是private ,除了Child之外没有人知道继承。

限制继承的可见性将使代码无法看到某些类继承另一个类:从派生到基础的隐式转换将不起作用,并且从基础到派生的static_cast也不起作用。

只有类的成员 / 朋友才能看到私有继承,只有成员 / 朋友和派生类才能看到受保护的继承。

公共继承

  1. IS-A 继承。按钮是一个窗口,在需要窗口的任何地方,也可以传递按钮。

    class button : public window { };

受保护的继承

  1. 受保护的实施条款。很少有用。在boost::compressed_pair中用于从空类派生并使用空基类优化来保存内存(下面的示例不使用模板来保持这一点):

    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!
      }
    };

私人继承

  1. 实现合条件方面。基类的用法仅用于实现派生类。对 traits 有用,如果 size 很重要(只包含函数的空特征将使用空基类优化)。但是,通常遏制是更好的解决方案。字符串的大小是至关重要的,因此这是一个常见的用法

    template<typename StorageModel>
    struct string : private StorageModel {
    public:
      void realloc() {
        // uses inherited function
        StorageModel::realloc();
      }
    };

公共成员

  1. 骨料

    class pair {
    public:
      First first;
      Second second;
    };
  2. 访问器

    class window {
    public:
        int getWidth() const;
    };

受保护的成员

  1. 为派生类提供增强的访问权限

    class stack {
    protected:
      vector<element> c;
    };
    
    class window {
    protected:
      void registerClass(window_descriptor w);
    };

私人会员

  1. 保持实施细节

    class window {
    private:
      int width;
    };

请注意,C 样式转换有意允许以定义和安全的方式将派生类转换为受保护的或私有的基类,并且也可以转换到另一个方向。应该不惜一切代价避免这种情况,因为它可以使代码依赖于实现细节 - 但如果有必要,您可以使用这种技术。