私人继承

nit*_*man 7 c++ inheritance

我完全不懂这个:

class Base
{
    public:
    Base()
    {
        cout<<"Base" << endl;
    }

    virtual void call()
    {
        cout<<"Base call" << endl; 
    }
};

class Derived: private Base
{
    public:      
    Derived()
    {
        cout<<"Derived" << endl;
    } 
};

int main(void)
{
    Base *bPtr = new Derived(); // This is not allowed
}
Run Code Online (Sandbox Code Playgroud)

是因为有人可能使用bPtr调用call(),这实际上是在派生对象上完成的?或者还有其他原因吗?

Kon*_*lph 19

从对继承的共同理解来看,C++的"私有继承"是一个可怕的误称:它不是继承(就类的所有内容而言),而是类的完整实现细节.

从外部看,私人继承实际上与构成完全相同.只有在类的内部才能获得特殊的语法,这种语法更像是继承而不是组合.

但有一点需要注意:C++在语法上将其视为继承,具有所需的所有好处和问题,例如范围可见性和可访问性.此外,C风格的强制转换(但没有C++强制转换!)实际上忽略了可见性,因此成功地将Derived指针转换为Base:

Base* bPtr = (Base*) new Derived();
Run Code Online (Sandbox Code Playgroud)

不用说,这是邪恶的.

  • 它是实现继承而不是接口继承. (7认同)
  • @curiousguy(我不知道为什么我甚至打扰)看到我对Laurence评论的回答.另外,我知道它是一种简化(即使在类之外的C风格转换也能够在私有继承层次结构中进行转换).但是对于私有继承来说,这是一个有用的(*我认为最有用的)直觉. (2认同)

Kaz*_*gon 19

公共继承意味着每个人都知道Derived是从Base派生的.

受保护的继承意味着只有Derived,Derived的朋友和派生自Derived的类知道Derived派生自Base.*

私有继承意味着只有Derived和Derived的朋友知道Derived是从Base派生的.

由于您使用了私有继承,因此main()函数没有关于从base派生的线索,因此无法分配指针.

私有继承通常用于实现"is-implemented-in-terms-of"关系.一个例子可能是Base公开了一个你需要覆盖的虚函数 - 因此必须继承 - 但你不希望客户知道你有这种继承关系.

*还有:土拨鼠砍多少木头......

  • 三年半之后,我的答案的附录:在私有继承的情况下,请注意,甚至Base都不知道Derived是从Base派生的.也就是说,如果Derived私有地从Base继承,则Base的成员函数中的`dynamic_cast <Derived*>(this)`将始终返回NULL.我之所以提到这一点是因为它最近在尝试通过Curiously Recursive Template Pattern传入的类的私有继承时咬了我一下. (4认同)

sbi*_*sbi 9

因为private意味着"实现细节",这使得事实Derived源于Base实现细节.

私有继承不是接口继承,而是实现继承.它不实现"Is-A"关系,而是实现"Is-Implemented-Using"关系.DerivedBase类的用户而言,它不是一个问题,而是恰好(目前)使用它来实现.