c ++中受保护的派生和私有派生有啥区别[重复]

Posted

技术标签:

【中文标题】c ++中受保护的派生和私有派生有啥区别[重复]【英文标题】:What is difference between protected and private derivation in c++ [duplicate]c ++中受保护的派生和私有派生有什么区别[重复] 【发布时间】:2011-08-19 18:02:55 【问题描述】:

可能重复:Difference between private, public and protected inheritance in C++

在 C++ 中导出为受保护或私有有什么区别?我无法弄清楚,因为两者似乎都限制了派生类对象的基类成员访问

【问题讨论】:

坦率地说,两者都有点浪费空间。在超过 25 年的专业 C++ 编程中,我从来没有在愤怒中使用过任何一种。 @unapersson:我从未使用过受保护的继承,但我以前使用过私有继承。类从只读接口公开继承,从读写接口私下继承。然后它可以将自己传递给期望读写接口的函数,但任何其他类或函数都必须使用只读接口。节省了宣布朋友。在 Builder 模式的实现中使用它。 @Daniel 对我来说,组合总是会战胜私有继承,因为它减少了耦合。但是YMMV。受保护的继承一直是一个螺栓 - 我似乎记得它是在 cfront 2.x 的某个时候添加的,仅仅是因为有人认为公共/受保护/私有访问应该反映在继承说明符中。但也许我的记忆在耍花招。 @unapersson:私有继承有时对于从 boost::noncopyable 之类的东西派生很有用。也就是说,当您尝试隐藏界面(复制 ctor 等)而不是公开界面时。 我想指出私有继承的一个重要用途是启用空基优化。除此之外,我觉得从不使用它很舒服。 【参考方案1】:

让我们考虑一个代码示例,显示使用不同级别的继承允许(或不允许)什么:

 class BaseClass ;

 void freeStandingFunction(BaseClass* b);

 class DerivedProtected : protected BaseClass
 
     DerivedProtected()
     
         freeStandingFunction(this); // Allowed
     
 ;

DerivedProtected 可以将自己传递给freeStandingFunction,因为它知道它派生自BaseClass

 void freeStandingFunctionUsingDerivedProtected()
 
     DerivedProtected nonFriendOfProtected;
     freeStandingFunction(&nonFriendOfProtected); // NOT Allowed!
 

非朋友(类、函数等)不能将DerivedProtected 传递给freeStandingFunction,因为继承受到保护,因此在派生类之外不可见。私有继承也是如此。

 class DerivedFromDerivedProtected : public DerivedProtected
 
     DerivedFromDerivedProtected()
     
         freeStandingFunction(this); // Allowed
     
 ;

DerivedProtected 派生的类可以看出它继承自BaseClass,因此可以将自身传递给freeStandingFunction

 class DerivedPrivate : private BaseClass
 
      DerivedPrivate()
      
          freeStandingFunction(this); // Allowed
      
 ;

DerivedPrivate 类本身知道它派生自BaseClass,因此可以将自己传递给freeStandingFunction

class DerivedFromDerivedPrivate : public DerivedPrivate

     DerivedFromDerivedPrivate()
     
          freeStandingFunction(this); // NOT allowed!
     
;

最后,继承层次结构中的非友元类无法看到DerivedPrivate 继承自BaseClass,因此无法将自身传递给freeStandingFunction

【讨论】:

所以有受保护/私有继承的“有用”应用程序。谢谢你的好例子。【参考方案2】:

使用这个矩阵(取自here)来决定继承成员的可见性:

继承\成员 |私人 |受保护 |民众 -----------------+-----------------+------------ ----+-------------- 私人 |无法访问 |私人 |私人的 受保护 |无法访问 |受保护 |受保护 公共 |无法访问 |受保护 |民众 -----------------+-----------------+------------ ----+--------------

示例 1:

class A  protected: int a; 
class B : private A ;       // 'a' is private inside B

示例 2:

class A  public: int a; 
class B : protected A ;     // 'a' is protected inside B

示例 3:

class A  private: int a; 
class B : public A ;        // 'a' is inaccessible outside of A

【讨论】:

【参考方案3】:

private 只允许声明它的类访问它 protected 允许该类和派生/子类像私有一样访问

【讨论】:

【参考方案4】:

我在this Q 中添加了关于InheritanceAccess Specifiers 的非常详细的解释。它解释了所有类型的继承以及访问说明符如何与它们一起工作。看看吧。 第 :)

【讨论】:

【参考方案5】:

基本上,protected 继承在继承层次结构中比private 继承延伸得更远。有关详细信息,请参阅the C++ FAQ Lite。

【讨论】:

以上是关于c ++中受保护的派生和私有派生有啥区别[重复]的主要内容,如果未能解决你的问题,请参考以下文章

受保护的与私有的析构函数

C++ - 在派生类中静态初始化基类受保护的成员变量

.Net中受保护的内部意味着啥[重复]

python中受保护变量和公共变量有啥区别

如何影响派生类中受保护的基变量

C++17 中受保护构造函数的规则改变了吗?