1

Angenommen, eine Klasse Y erbt öffentlich eine Klasse X. Ist es möglich, dass eine Klasse ZY privat erbt und gleichzeitig X erbt?Gleichzeitige private und öffentliche Vererbung in C++

Um dies klarer zu machen, angenommen X definiert öffentliche Methoden x1 und x2. Y erbt X, überschreibt x1 und bietet eine Methode y. Hat C++ für eine dritte Klasse ermöglicht ZY so zu Unterklasse, die Y ‚s Implementierung von x1 und y privat zur Verfügung steht, um es, während die Außenwelt nur sieht X öffentlich zu erben, das heißt, das nur eine einzige öffentliche Methode x2?

+0

Wenn Sie auch "faule Helfer" möchten, um Ihnen zu helfen, würde ich diese Frage im Code so weit wie möglich schreiben, dann darauf hinweisen, wo es nicht funktioniert, und dann die Frage auf eine Zeile reduzieren und fragen, wie mach diese Arbeit. – AudioDroid

Antwort

4

Ja, dies wird virtuelle Vererbung genannt.

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

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

struct Z : private Y, virtual X { 

}; 

Menschen können z.y() oder z.x1() nicht tun, aber sie können z.x2() tun und einen Z* zu einem umwandeln kann. Aber sobald sie dies tun, können sie natürlich converted->x1()undconverted->x2() anrufen.

Sie haben etwas über dein Ziel nicht gesagt, aber es klingt wie Sie wirklich Y als Zeiger halten wollen, obwohl

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

Dies ist für mich besser vertraut aussieht.

+1

Vielen Dank für eine klare Antwort, die mich über ein Konzept informiert, von dem ich vorher noch nichts wusste, was genau die Rolle erfüllt, die ich ausfüllen wollte. Entschuldigung für die Frage, was scheinbar eine triviale Frage war. Es kann schwierig sein zu wissen, dass etwas trivial ist, wenn man nicht weiß, wie es heißt :-) – gspr

2

Sicher. Sie könnten using X::x2 in einem public: Abschnitt verwenden. Wenn Y x2 überschreibt, ignorieren Sie diese Überschreibung natürlich.

2

Zunächst einmal, ich bin mir nicht ganz sicher, ob ich Ihren letzten Satz verstehe.

Does ++ C für eine dritte Klasse von Z nach Unterklasse Y in einer solchen Art und Weise ermöglichen, dass Implementierung von x1 des Y und y privat zur Verfügung zu ihm sind, während die nur Außenwelt es X öffentlich vererben sieht, dh mit nur einer einzigen öffentlichen Methode x2?

Wenn Z öffentlich von X erbt, dann beide x1 und x2 zur Verfügung: obwohl die Zugänglichkeit von x2kann in Z geändert werden, nichts hindert die Außenwelt von einem Z durch einen X Zeiger manipulieren und rufen Sie x2.

Dass gesagt wird, könnte man genauso gut haben Z erben privat von Y und öffentlich von X obwohl, wie von Johannes wies darauf hin, Sie in virtuelle Vererbung aussehen sollte als Z so zweimal von X erben.


Je nach Bedarf, können Sie auch in die decorator pattern aussehen wollen (vielleicht ist es völlig unabhängig, aber aus irgendeinem Grund, ich fühle mich Ihre Frage durch das Lesen, dass es ist, was Sie erreichen wollen):

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

In diesem schnellen und schmutzigen Codebeispiel Zist einX (öffentliche Vererbung), doch ist Y Implementierung wiederverwendet.

+0

Was ist das explizite Schlüsselwort? – ykatchou

+1

schön, du hast mich mit dem "Setze dich als Zeiger" Weg geschlagen! Ich wusste, dass es einen Namen hatte, aber ich konnte nicht für das Leben von mir herausfinden, dass es "Dekorateur" genannt wird :) –

+0

Auch eine sehr aufschlussreiche Antwort. Danke besonders dafür, dass Sie mich über 'explizit' informiert haben. – gspr

2

Ich denke, dass Anweisung füllt diese Rolle besser, ermöglicht es Ihnen auf Z zu spezifizieren, die private Methoden zur Verfügung stehen wird:

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

Wenn Sie nicht-virtuelle Vererbung von X in Ihnen an mindestens einer Stelle Erhalten Sie zwei unterschiedliche X-Unterobjekte mit unterschiedlichen Zugriffspfaden und Zugriffsrechten.

Wenn Sie die virtuelle Vererbung von X an beiden Stellen verwenden, sollten Sie die öffentliche Vererbung an beiden Stellen verwenden, da der Zugriff über die virtuelle Vererbung nicht erzwungen werden kann. Wenn Sie eine Ableitung nicht öffentlich machen, können Sie weiterhin den anderen Pfad verwenden, um Zugriff zu erhalten. Wenn keine Ableitung öffentlich ist, können Sie nur eine andere Klasse ableiten, in der es sich befindet. Daher kann nicht-öffentliche virtuelle Vererbung vom Typsystem nicht erzwungen werden und ist daher Unsinn und hätte in der Sprache niemals erlaubt sein sollen.