C ++中的同时私有和公共继承

时间:2010-12-28 13:17:31

标签: c++ inheritance virtual-functions virtual-inheritance private-inheritance

假设某个班级Y公开继承了一个班级X。在公开继承Z时,课程Y是否可以私下继承X

为了更清楚,假设X定义了公共方法x1x2Y继承X,覆盖x1并提供方法y。 C ++是否允许第三个类ZY的{​​{1}}实现Yx1为子类y进行子类化,而外界只看到它公开继承X,即只有一个公共方法x2

5 个答案:

答案 0 :(得分:4)

是的,这称为虚拟继承。

struct X {
  virtual void x1();
  void x2();
};

struct Y : virtual X {
  void x1(); // overrides
  void y();
};

struct Z : private Y, virtual X { 

};

人们无法z.y()z.x1(),但他们可以z.x2()并且可以将Z*转换为X*。但是,一旦他们这样做,他们当然可以致电converted->x1() converted->x2()

你还没有说过你的目标,但听起来你真的想把Y作为指针而不是

struct X {
  virtual void x1();
  void x2();
};

struct Y : X {
  virtual void x1(); // overrides
  void y();
};

struct Z : X { 
  virtual void x1() { // overrides
    /* uses y->x1 */ 
  }
  Y *y;
};

这对我来说更为熟悉。

答案 1 :(得分:2)

不确定。您可以在using X::x2部分中使用public:。当然,如果Y覆盖x2,那么你将忽略这个覆盖。

答案 2 :(得分:2)

首先,我不太清楚我理解你的最后一句话。

  

C ++是否允许使用第三类Z.   子类Y以Y的方式   x1和y的实现是   私人可用,而   外界只看到它继承   公开X,即只有一个   公共方法x2?

如果ZX公开继承,则x1x2都可用:虽然x2 的可访问性可能Z中进行更改,不会阻止外部世界通过Z指针操纵X并致电x2

话虽如此,您可能Z私下从Y继承并公开从X继承,但正如Johannes所指出的,您应该将虚拟继承看作Z。因此,1}}将从X继承两次


根据您的需要,您可能还需要查看decorator pattern(也许它完全不相关,但出于某种原因,我通过阅读您的问题感觉这是您想要实现的目标):

class X
{
public:
    virtual void x1();
    virtual void x2();
};

class Y : public X
{
public:
    virtual void y();
    virtual void x1();
};

class Z : public X
{
public:
    explicit Z(X *x) : x_(x) {}

    virtual void x1() { x_->x1(); }
    virtual void x2() { x_->x2(); }

private:
    X *x_;
};

int main()
{
    Y y;
    Z z(&y);
}

在这个快速而又脏的代码示例中,Z X(公共继承),但重用 Y实施

答案 3 :(得分:2)

我认为using语句更好地填充了这个角色,它允许你在Z上指定哪些私有方法可用:

class X
{
    public:
        virtual void x1() {}
        virtual void x2() {}

};

class Y: public X
{
public:
    virtual void x1() {}
};

class Z: private Y
{
public:
    using X::x2;

};

答案 4 :(得分:0)

如果在至少一个地方使用X的非虚拟继承,则会获得具有不同访问路径和访问权限的两个不同的X子对象。

如果在两个地方使用X的虚拟继承,则应该在两个地方都使用公共继承,因为无法通过虚拟继承进行访问。如果您将一个派生非公开,您仍然可以使用其他路径获取访问权限。如果这两个派生都不是公共的,那么你只能派生出另一个类,因此,类型系统不能强制执行非公共虚拟继承,因此它是无意义的,并且永远不应该被允许使用该语言。