1

クラスYがクラスXを公的に継承しているとします。クラスZは、Yを非公開で継承し、公開している間にXを継承することは可能ですか?C++でのプライベートとパブリックの同時継承

Xがパブリックメソッドx1x2を定義しているとします。 YXを継承し、x1を上書きし、方法yを提供する。 C++は外の世界にのみ、それはすなわち、単一のパブリックメソッドx2を持つ、公にXを継承見ながらx1yYの実装は、それに私的に利用できるようにYをサブクラス化する第三のクラスZを可能にしていますか?

+0

「怠惰なヘルパー」もお手伝いしたいなら、できる限りコードにこの質問を書いて、それがうまくいかない場所を指摘して質問を1行に減らし、その仕事をしてください。 – AudioDroid

答えて

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*を変換することができます。しかし、一度そのようにすれば、converted->x1()converted->x2()と呼ぶことができます。

あなたはあなたの目標については何も言っていませんが、これは私にはより身近に見える

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; 
}; 

かかわらず、あなたが本当にポインタとしてYを維持したいように聞こえます。

+1

私が以前に知りませんでした概念について教えてくれてありがとうございました。些細な質問であると思われるものを聞いて申し訳ありません。それが何であるかわからないときに何かが自明であることを知るのは難しいかもしれません:-) – gspr

2

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

2

まず、あなたの最後の文章を理解しているかどうかはわかりません。

んC++ 外の世界だけ公にそれが Xを継承見ながらx1とYのYの 実装は、それに 私的に利用できるような方法で サブクラスYに第三クラスZを可能に、すなわち、パブリックメソッドx2を1つしか持たないか?

ZXから公に継承する場合は、x1x2の両方が利用できるようになります:x2のアクセスがZ変更されるかもしれないが、何もXポインタを通じてZを操作するから外の世界を防止していないし、 x2に電話してください。

言われていること

、あなたにもZは、ヨハネスで指摘したようにZは、このようにXから2回を継承するとして、あなたは仮想継承になっているはずです、しかし個人Yからと公に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); 
} 

ZX(パブリック継承)され、まだY実装を再利用しています。

+0

明示的なキーワードは何ですか? – ykatchou

+1

素敵な、あなたは "ポインタとしてのyを置く"方法で私を殴った!私はそれがいくつかの名前を持って知っていたが、私は私の人生のためにそれが "デコレータ"と呼ばれていることを理解できませんでした:) –

+0

また非常に啓発の答え。特に明示的に私に教えてくれてありがとう。 – gspr

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; 

}; 
0

あなたは、少なくとも一箇所にXの非仮想継承を使用している場合異なるアクセスパスとアクセス権を持つ2つの異なるXサブオブジェクトを取得します。

両方の場所でXの仮想継承を使用する場合、仮想継承によるアクセスは強制できないため、両方の場所で公開継承を使用する必要があります。 1つの派生物を非公開にすると、他のパスを使用してアクセスすることができます。いずれの派生も公開されていない場合、それが存在する別のクラスを派生させるだけで、非publicな仮想継承は型システムによって強制できないので、ナンセンスであり、決して言語で許可されるべきではありません。