1

クラスがクラスYをパブリックに継承するとしXます。クラスがパブリックに継承しながらZプライベートに継承することは可能ですか?YX

これをより明確にするために、パブリック メソッドと をX定義するとします。メソッドを継承し、オーバーライドし、提供します。C++ では、3 番目のクラスをサブクラス化して、その実装をプライベートに利用できるようにすることができますが、外部の世界では、それがパブリックに継承されている、つまりパブリック メソッドが 1 つしかないことがわかりますか?x1x2YXx1yZYYx1yXx2

4

5 に答える 5

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()orを行うことはできませんz.x1()が、行うことはでき、 aを に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;
};

これは私にとってより身近に見えます。

于 2010-12-28T13:30:34.143 に答える
2

ステートメントを使用すると、この役割がより適切に満たされると思います。これにより、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;

};
于 2010-12-28T14:21:11.113 に答える
2

もちろん。using X::x2セクションで使用できますpublic:。もちろん、Y が x2 をオーバーライドする場合、このオーバーライドは無視されます。

于 2010-12-28T13:29:20.160 に答える
2

まず第一に、私はあなたの最後の文をよく理解していません.

C++ は、Y の x1 と y の実装がプライベートに利用できるように、3 番目のクラス Z が Y をサブクラス化することを許可しますが、外部の世界では X をパブリックに継承する、つまり単一のパブリック メソッド x2 しか持たないことだけを認識しますか?

がからパブリックZに継承する場合、とXの両方が利用可能になりますx1x2x2 ZZXx2

そうは言っても、ヨハネスが指摘したように、からZプライベートに継承しYたり、パブリックに継承したりすることもできますが、から2回継承するため、仮想継承を検討する必要があります。XZX


必要に応じて、デコレータ パターンを調べることもできます(完全に無関係かもしれませんが、何らかの理由で、あなたの質問を読んで、それがあなたが達成したいことだと感じています)。

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

于 2010-12-28T13:37:33.497 に答える
0

少なくとも 1 つの場所で X の非仮想継承を使用すると、別個のアクセス パスとアクセス権を持つ 2 つの別個の X サブオブジェクトが得られます。

X の仮想継承を両方の場所で使用する場合は、仮想継承によるアクセスを強制できないため、両方の場所でパブリック継承を使用する必要があります。一方の派生を非公開にしても、もう一方のパスを使用してアクセスすることができます。どちらの派生もパブリックでない場合は、それがパブリックである別のクラスを派生させることができます。したがって、型システムによって非パブリックの仮想継承を強制することはできず、ナンセンスであり、言語で許可されるべきではありません。

于 2010-12-28T22:49:33.770 に答える