【问题标题】:Private Inheritance and Derived Object to Base reference私有继承和派生对象到基引用
【发布时间】:2012-05-15 18:01:00
【问题描述】:

据我了解,我们不能将派生类对象传递给基类引用以进行私有继承的原因是,由于 Derived 是从 Base 私有继承的,因此会在 Derived 的构造函数之前调用 Base 的默认构造函数。但是因为它是私有的并且没有继承给 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 抛出一个错误(将私有继承的构造函数公开给公共)。 我正在尝试的是否有效?谁能告诉我?

【问题讨论】:

    标签: c++


    【解决方案1】:

    我们不能有一个对私有继承的派生对象的基类引用是因为这会违反Liskov Substitution Principle:派生对象IS-NOT-A基类对象,因为它不提供基类公共接口.您无法解决此问题

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

    您可以阅读here(请务必点击所有链接)了解更多关于何时私有继承是一个不错的选择的信息(总结:当没有其他选择时)。

    【讨论】:

      【解决方案2】:

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

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

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

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

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

      【讨论】:

      • 感谢您的解释。出于好奇,我还有一个疑问。我知道当从基类私有继承时,我们可以在派生类中公开基类的公共方法。但是我们可以对 base 的公共构造函数做同样的事情吗?有效吗?
      • 不,你有义务创建一个简单的构造函数,例如:derived(): base() {}。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-11
      • 2017-05-07
      相关资源
      最近更新 更多