2012-04-03 23 views
7

mam ten kod:wirtualne funkcje nadrzędne i ukrywanie

class Event{}; 
class CustomEvent:public Event{}; 

class Handler 
{ 
    public: 
     virtual void inform(Event e){} 
}; 

class CustomHandler : public Handler 
{ 
    public: 
    void inform(CustomEvent e){}   

}; 

CustomEvent cEvent; 
Handler* handler = new CustomHandler; 

//this calls Handler::inform(Event), not CustomHandler::(CustomEvent) , as I expected 
handler->inform(cEvent); 

Gdybym zmienić kod do tego:

class Handler 
{ 
    public: 
     virtual void inform(Event e){} 
     virtual void inform(CustomEvent e){} 

}; 

class CustomHandler : public Handler 
{ 
    public: 
    void inform(CustomEvent e){}   

}; 

CustomEvent cEvent; 
Handler* handler = new CustomHandler; 

//this calls CustomHandler::(CustomEvent) 
handler->inform(cEvent); 

Czytałem, że jest to związane z funkcji legionella i ukrywanie ale nadal robi” t zrozumieć zachowanie w tym kodzie.

+3

Wiele rzeczy jest nie tak z kodem. Na początek argumenty funkcji powinny być * referencjami *. –

+0

Dlaczego referencje? – user152508

+2

Z powodu (a) krojenia i (b) niepotrzebnej kopii. – ipc

Odpowiedz

9

Funkcja przeciążenia nie działa w oparciu o wykonawczego typu argumentów (co do argumentu Oto CustomHandler*), ale raczej na ich statycznej typu (który tutaj jest Handler*, jak to co handler jest zadeklarowana jako) .

Funkcje wirtualne umożliwiają wykonywanie wywołań funkcji na podstawie typu środowiska wykonawczego obiektu jeden obiekt (ten, na który wywoływana jest funkcja). Wysyłanie wywołań w oparciu o typ środowiska wykonawczego wielu obiektów nazywa się wielokrotną wysyłką; w tym miejscu mówimy o najczęstszym przypadku double dispatch. Jeśli chcesz tego rodzaju funkcjonalności, będziesz musiał wdrożyć podwójną wysyłkę lub skorzystać z biblioteki, która zrobi to za ciebie.

The Visitor pattern jest dość powszechnym sposobem wykonania; patrz także Difference betwen Visitor pattern & Double Dispatch.

Wreszcie można znaleźć dobrą dyskusję na temat odwiedzającego, która zawiera przykładowy kod (przewiń w dół) here.

+0

+1 napisałeś, co zamierzałem odpowiedzieć. oprócz tego, że planowałem dołączyć przykład konkretnego wzoru dla odwiedzających. proszę dodać, że –

+0

@ Cheersandhth.-Alf: Dodano link, który powinien zrobić dobrze. Nie chciałem dodawać przykładu w wierszu (za dużo tablicy). – Jon