2016-11-29 5 views
11

Betrachten Sie folgendes:Kann man Teile der Vererbungshierarchie in C++ verstecken?

Klasse B erbt öffentlich von Klasse A. Beide sind in einer Bibliothek enthalten und ich kann sie nicht ändern.

Ich möchte eine Klasse implementieren Foo, die von B leitet, aber ich möchte den Benutzern von Foo erlauben nur öffentliche Funktionen von A und Foo (nicht von B) zu verwenden. Für sie ist es nicht relevant, dass Foo von B erbt, das ist im Prinzip ein Implementierungsdetail, das ich nicht vermeiden kann.

Also, im Prinzip möchte ich Foo erben öffentlich von A, aber privat von B.

Gibt es ein Konstrukt in C++, das mir erlauben würde, dies zu tun?

Ich muss hinzufügen, dass die virtuelle Vererbung keine Option ist, da A, in meinem Fall, von QObject abgeleitet ist (siehe Is it safe to use *virtual* multiple inheritance if QObject is being derived from DIRECTLY?).

(NB: Für Interessenten: in meinem Fall ist AQWindow und B ist Qt3DExtras::Qt3DWindow)

+1

tut 'struct foo: A {B b; } 'Arbeit? – Danh

+1

Dokumentieren Sie einfach nicht, dass Ihre Klasse von B abgeleitet ist. Sagen Sie, dass sie von A abgeleitet ist. Dies ist keine Methode, um einen bestimmten Benutzer, der Zugriff auf B haben will, zu stoppen, aber dann ist nichts anderes mehr. –

Antwort

9

Die nächstgelegene Sie in c tun ++ ist dies: Da diese

class Foo : private B { 
    public: 
    using A::foo; // Expose function foo in Foo's API. 
    using A::bar; 
    operator A&() { return *this; } // Implicit conversion to `A` when needed. 
    operator A const&() const { return *this; } 
}; 
+2

'A * a = pointer_to_foo', das ist der wichtige Teil von Qt, funktioniert nicht – Danh

+0

@Danh, ein weiterer Grund, Referenzen zu bevorzugen. Sie können keine Zeigerkoordination hinzufügen, da sie integrierte Typen sind. Das OP muss explizit casten. – StoryTeller

+0

ja, ich bevorzuge auch Referenzen, aber AFAIK ist, wie Qt im Allgemeinen funktioniert – Danh

2

ist Qt, I denke, das ist das nächste, was du tun kannst:

struct Foo : A { 
    // override all function of A, forward its to B 
private: 
    B b; // or pointer to B, it's depend on your design 
}; 
+0

Dies gibt Ihnen zwei 'A's innerhalb eines' Foo', das ererbte und eins als Teil von 'b'. (Genauer gesagt gibt es zwei 'QWindows', die falsch klingen - das ist nur * ein * Fenster, oder?) Das mag nicht erwünscht sein. Ich nehme auch an, dass ein "Foo" * * sein muss, beispielsweise weil ein Zeiger darauf als ein Zeiger auf ein "B" gespeichert ist. –

+0

@ PeterA.Schneider OP sagte _Für sie ist es nicht relevant, dass Foo von B erbt – Danh

+0

Nicht für die * Benutzer *, aber irgendwo muss eine Anforderung sein - es kann schließlich nicht vermieden werden. –

Verwandte Themen