1

据我了解,我们不能将派生类对象传递给基类引用以进行私有继承的原因是,由于 Derived 是从 Base 私有继承的,因此 Base 的默认构造函数将在 Derived 的构造函数之前调用。但是因为它是私有的并且没有继承给 Derived,所以我们得到一个编译器错误。

但是,如果我尝试为 Base 创建一个公共构造函数并私下从 Derived 继承,然后将公共状态重新分配给 Base 的构造函数,它是否允许我将派生的实例传递给 Base 引用?

我尝试如下,

#include <iostream>

using namespace std;

class base
{
      public:
             base(){}
             void print(){ puts("In base"); }
};

class derived : private base
{
      public:
             base::base;   /* Throws an error - Declaration doesnt declare anything*/
             void print(){ puts("In derived"); }
};

void func(base& bRef)
{
}

int main()
{
    derived dObj;
    func(dObj); /*  Throws an error - 'base' is an inaccessible base of derived */
}

它为 base::base 抛出错误(将私有继承的构造函数公开)。我正在尝试的是否有效?谁能告诉我?

4

2 回答 2

4

我们不能有对私有继承的派生对象的基类引用的原因是因为这将违反Liskov 替换原则:派生对象 IS-NOT-A 基类对象,因为它不提供基类公共接口。您无法解决此问题

出于这个原因,私有继承是一种重用实现的方式,而不是当您想要制作更专业的类型时。由于大多数时候这可以通过组合来完成(即拥有基类的成员而不是私有派生),因此私有继承可能是一种不好的代码味道。

您可以在此处阅读(请务必点击所有链接)以获取有关何时私有继承是一个不错选择的更多信息(总结:当根本没有其他选择时)。

于 2012-05-07T07:58:52.253 回答
2

不,用基类的指针或引用指向 Derived 的对象是无效的。如果可能,那么私有继承的全部目的(隐藏派生类从基类继承其部分(或全部)功能的事实)将毫无用处。

假设您foo()在基类中有一个方法。您不希望调用此方法。但是,如果可以从基类的指针指向对象,那么也可以调用foo().

Base * ptrBase = &objDerived;      // Let's suppose this would compile
ptrBase->foo();                    // Now we can call foo() (?)

当您声明私有继承时,就好像派生类与基类无关。只有您,开发人员,唯一应该“知道”这种关系存在的人,实际上您应该忘记它,因为它根本行不通。

私有继承只是作为一种可重用机制,而不是真正的继承机制。甚至不建议使用它,因为您可以通过简单地应用组合来获得更好的结果(即只需在 Derived 中创建类 Base 的属性)。

于 2012-05-07T08:00:04.743 回答