2016-11-29 18 views
11

Rozważ następujące informacje:Czy można ukryć części hierarchii dziedziczenia w C++?

Klasa dziedziczy publicznie z klasy A. Oba są dostarczane w bibliotece i nie mogę ich modyfikować.

Chcę zaimplementować klasę Foo który wynika z B, ale chcę, aby umożliwić użytkownikom Foo używać tylko funkcje publiczne z A i Foo (nie z B). Dla nich nie ma znaczenia, że ​​Foo dziedziczy po B, jest to w zasadzie szczegół implementacji, którego nie mogę uniknąć.

Tak więc, w zasadzie chcę, aby Foo dziedziczył publicznie od A, ale prywatnie od B.

Czy jest jakiś konstrukt w C++, który pozwoliłby mi to zrobić?

Muszę dodać, że dziedziczenie wirtualne nie wchodzi w grę, ponieważ A, w moim przypadku, pochodzi z QObject (patrz: Is it safe to use *virtual* multiple inheritance if QObject is being derived from DIRECTLY?).

(NB: Dla zainteresowanych: w moim przypadku, A jest QWindow i B jest Qt3DExtras::Qt3DWindow)

+1

robi 'struct foo: A {B b; } 'praca? – Danh

+1

Po prostu nie dokumentuj, że twoja klasa pochodzi od B. Powiedzmy, że wywodzi się z A. To nie jest metoda zatrzymania określonego użytkownika, który chce uzyskać dostęp do B, ale wtedy nic innego nie jest. –

Odpowiedz

9

Najbliższy można zrobić w C++ to:

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', który jest ważną częścią Qt, nie działa – Danh

+0

@Danh, kolejny powód do preferowania referencji. Nie można dodawać wymuszenia wskaźnika, ponieważ są one wbudowane. PO będzie musiał wyraźnie oddać. – StoryTeller

+0

tak, ja również wolę używać referencji, ale AFAIK to, jak działa Qt w ogóle – Danh

2

Ponieważ jest to Qt, I myśl, że to jest najbliższe, co możesz zrobić:

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

To daje dwa 'A's wewnątrz' Foo', odziedziczony i jeden jako część 'b'. (W szczególności istnieją dwa 'QWindow's, które brzmią źle - to tylko * jedno * okno, prawda?) To może nie być pożądane. Przypuszczam również, że 'Foo' musi * być * a' B', na przykład ponieważ wskaźnik do niego jest zapisany jako wskaźnik do 'B'. –

+0

@ PeterA.Schneider OP powiedział: "Dla nich nie ma znaczenia, że ​​Foo dziedziczy po B_ – Danh

+0

Nie dla * użytkowników *, ale gdzieś musi być wymaganie - nie da się go jednak uniknąć. –