2009-11-14 11 views
8

Załóżmy, że mam niektóre kodu tak:Przeciążenie metody w podklasie w C++

class Base { 
    public: 
     virtual int Foo(int) = 0; 
}; 

class Derived : public Base { 
    public: 
     int Foo(int); 
     virtual double Foo(double) = 0; 
}; 

class Concrete : public Derived { 
    public:   
     double Foo(double); 
}; 

Jeśli mam obiekt typu betonu, dlaczego nie mogę zadzwonić foo (int)?
Jeśli zmienię nazwę Foo (podwójną), tak aby nie przeciążała Foo, wtedy wszystko jest dobrze i obie metody są dostępne, ale to nie jest to, czego chcę.
Podobnie, jeśli usuniemy klasę Concrete i zaimplementuję Foo (double) w Derived, to oba są dostępne, ale znowu nie to, czego chcę.

+0

Nie rozumiem problemu. GCC wersje 3.3.6 i 4.2.4 zarówno kompilują ten kod bez skargi. –

+0

Z powodu niejawnej konwersji liczb całkowitych do podwójnych - spróbuj dodać śledzenie do funkcji i wykonaj polecenie "Konkretne c; int i = 1; c.Foo (i); ' –

+0

Czy to nie jest nadpisywanie, jeśli przedefiniujesz wirtualną metodę w podklasie? – mucaho

Odpowiedz

14

Nazwa odnośnika dzieje przed przeciążeniem rozdzielczości, więc raz Foo został znaleziony w Concrete zajęcia bazowe nie będzie szukać innych metod zwanych Foo. int Foo(int) w Derived jest ukryty przez Foo w Concrete.

Masz wiele opcji.

Zmień połączenie, aby było jawne.

concrete.Derived::Foo(an_int); 

Dodaj deklarację użycia do betonu.

class Concrete : public Derived { 
public:   
    using Derived::Foo; 
    double Foo(double); 
}; 

Wywołanie funkcji przez odniesienie bazowe.

Derived& dref = concrete; 
dref.Foo(an_int); 
6

Foo(double) ukrywa funkcję z bazy. Można zrobić to widoczne choć:

class Concrete : public Derived 
{ 
public:   
    using Derived::Foo; 
    double Foo(double); 
}; 
+2

Dobre wyjaśnienie można znaleźć na stronie http://stackoverflow.com/questions/411103/function-with-same-name-but-different-signature-in-derived-class/411112#411112 –

Powiązane problemy