7

załóżmy niektóre (starsze) kod, który by nie mógł współczuć, oświadczamużyciu siostra dziedziczenie

struct B{ 
public: 
    void f(){} 
}; 

i załóżmy mieć

struct A{ 
public: 
    virtual void f()=0; 
}; 

jest możliwe zrób Wezwanie podklasa B :: f bez jawne wywołanie f(), czyli zamiast

struct C: public A, public B{ 
    void f(){ 
    B::f(); 
    } 
}; 

mający coś

struct C:virtual public A,virtual public B{ 

}; 

(zauważ, że ta ostatnia klasa jest abstrakcyjna, dla kompilatora A :: f nie jest uwzględniany)

+2

Co jest nie tak z 'B :: f()'? To jest właściwy sposób wywoływania 'B :: f()'. –

+0

wyobraź sobie, że masz 100 funkcji;) –

+2

Nie, nie ma możliwości, aby funkcje podstawowego elementu mogły * zaimplementować * czyste funkcje wirtualne dla innej klasy bazowej. To po prostu nie działa. To, co masz, jest w porządku. –

Odpowiedz

1

Bezpośrednio w C++, nie można wysłać polimorficznie w oparciu o pewne niejawne dopasowanie funkcji B do A. Możesz użyć jakiegoś generowania kodu za pomocą gccxml lub innych podobnych produktów, ale jeśli istnieje tylko sto funkcji, makro może zredukować przekazywanie do jednego liniowca - nie warto wprowadzać dodatkowych narzędzi, chyba że masz tysiące i tysiące te do zrobienia.

+0

"_dysuń polimorficznie w oparciu o pewne niejawne dopasowanie funkcji B do A's_" G ++ _used_ do obsługi tak zwanych "sygnatur": [Typ abstrakcji za pomocą podpisów] (http://gcc.gnu.org/onlinedocs/gcc-2.95 .3/gcc_5.html # SEC112) "W GNU C++ możesz użyć słowa kluczowego signature, aby zdefiniować całkowicie abstrakcyjny interfejs klasy jako typ danych. Możesz połączyć tę abstrakcję z rzeczywistymi klasami za pomocą wskaźników wskaźników. (...) Podtyp staje się niezależnie od dziedziczenia. (...) Podpisy umożliwiają pracę z istniejącymi hierarchiami klas jako implementacjami typu podpisu. " – curiousguy

+0

@ cosplay: to jest ogólne (historyczne dane usunięcie w gcc 3), ale nie widzę, w jaki sposób było to użyteczne dla robienia tego, o co chodzi w pytaniu, lub bardziej ogólnie o "wysyłce polimorficznej opartej na pewnym niejawnym dopasowaniu funkcji B do A "cytujesz. Biorąc pod uwagę 'signature S {void f(); }; ... S * p = static_cast (this); p-> f(); 'wydaje się funkcjonalnie równoważne powiedzeniu' std :: function x = std :: bind (& B :: f, this); x(); '- oba wydają się bardziej niezgrabne niż zwykłe wywoływanie' B :: f(); 'jak w pytaniu. Nie jestem pewien, czy czegoś brakuje ...? –

0

Można zrobić coś takiego:

void C::f() { 
    B* b = this; 
    b->f(); 
} 
+0

dziękuję, ale nie chcę pisać realizacji każdej funkcji (co więcej, jaka jest korzyść z tej wersji w stosunku do tej, którą napisałem?) –

+0

@FabioDallaLibera: Nie rozumiem. Jeśli nie chcesz pisać funkcji o nazwie 'f' w' C', to dlaczego deklarujesz taką funkcję? Nie ma różnicy między tą implementacją 'C :: f' a twoją w tym przypadku inną niż ta nie używa' B :: f', której chciałeś uniknąć. –

0

Nie, nie mogę tego zrobić że. A z fragmentu, który nam pokazałeś, wygląda na to, że powinno być członkiem C według kompozycji, a nie dziedziczenia. Musisz tylko napisać funkcje przekazywania (lub skrypt, który automatycznie je wygeneruje).

1

Złóż realizację A który deleguje do B:

class A_Impl : public A 
{ 
public: 
    virtual void f() 
    { 
     b.f(); 
    } 
private: 
    B b; 
} 

wdrożyć C przez pochodzące z A_Impl:

class C: public A_Impl 
{ 
}; 

Lub, jeśli tylko chcą pokazać A w hierarchii dziedziczenia, czerpią publicznie od A i prywatnie od A_Impl:

class C: public A, private virtual A_Impl 
{ 
}; 
-1

Masz 100 czystych wirtualnych funkcji w A, implementacje tych funkcji w B, i chcesz uniknąć zapisywania ponownego wdrożenia wszystkich tych funkcji w C, aby wywołać B. Nie ma sposobu, aby użyć kompilatora do użycia Implementacja B jest automatycznie. Zamiast walczyć z kompilatorem (będziesz przegrywać za każdym razem!), przemyśleć ponownie wykres dziedziczenia. Może sprawić, że B będzie podklasą A, a następnie wywodzić C z B. Lub współczynnik 100 metod z B i do konkretnej podklasy A.

Programowanie jest sztuką rozwiązywania problemów w ramach ograniczeń dostarczonych przez narzędzia. Kiedy znajdziesz się w sprzeczności z narzędziami, musisz albo przemyśleć swoje podejście do problemu, albo użyć różnych narzędzi.

+0

Pytanie brzmi, że B nie może zostać dotknięte, więc nie możesz uczynić go podklasą A, i nie możesz przenosić z niego metod. – Karu