2013-09-07 17 views
12

Planuję utworzyć interfejs (raczej wirtualną klasę podstawową w języku C++) za pomocą metody, która pobiera argument z własnego typu.Zastępowanie typu parametru funkcji z typem klasy pochodnej

class Base { 
public: 
    virtual void seriousMethod(const Base &arg) = 0; 
} 

Klasa pochodna nie powinna jednak przyjmować argumentu typu klasy bazowej, lecz typu klasy pochodnej.

class Derived: public Base { 
public: 
    virtual void seriousMethod(const Derived &arg) { /* ... */ } 
} 

Jak mógłbym to zrozumieć? Czy musiałbym szablon klasy podstawowej (np. Base<Derived>) lub czy istnieje czystsze rozwiązanie?

+0

Co ważniejsze - na czym polega motywacja? –

+0

"Klasa pochodna nie powinna jednak przyjmować argumentu typu klasy bazowej, ale typu klasy pochodnej" - o co w takim razie chodzi w ogóle o metody wirtualne? – berak

+0

@EdHeal Aby być konkretnym, należy określić klasę węzła wyszukiwania A-Star, która ma być określona przez pochodne implementacje. – Appleshell

Odpowiedz

13

Nie możesz tego zrobić bezpośrednio. Myśleć o tej sprawie:

Base b; 
Derived d; 
Base& d_ref = d; 
d_ref.seriousMethod(b); // What happens here? 

w czasie kompilacji, zmienna d_ref ma statyczny typ Base, więc zgodnie z definicją Base, powinien on być w stanie podjąć b jako parametr do seriousMethod.

Ale przy starcie, dynamiczny rodzaj d_ref jest Derived, więc zgodnie z definicją Derived, nie może wziąć b jako parametr do seriousMethod. Nie można przekonwertować b na Dervied, ponieważ może to być prosty obiekt Base (jeśli Base nie jest abstrakcyjny), lub może to być inna klasa pochodna od Base, która nie jest taka sama jak .

Jesteś słusznie zakładając, że jedynym sposobem, aby go o to ciekawie powtarzające wzór szablonu, czyli szablonów Base i definiowania Dervied jak:

class Derived : public Base<Derived> { ... } 

ta usuwa problem przedstawiony powyżej, ponieważ każdy typ wywodzący się z Base<T> będzie miał odrębną klasę podstawową i nie będzie powiązany ze sobą poprzez dziedziczenie.

Powiązane problemy