problem, który doświadczasz jest związane, jak działa wyszukiwanie nazw w C++. W szczególności podczas rozwiązywania elementu kompilator będzie sprawdzał typ statyczny obiektu, do którego członek jest uzyskiwany. Jeśli identyfikator zostanie znaleziony w tej klasie, to wyszukiwanie zakończy się i (w przypadku funkcji składowych) rozpocznie się obliczanie przeciążenia. Jeśli identyfikator nie zostanie znaleziony, będzie on indeksował hierarchię, klasy po klasie, próbując zlokalizować identyfikator o wartości na jednym poziomie w czasie.
W konkretnym przypadku masz c->onFoo();
i c
dla typu C
. Kompilator nie widzi żadnej deklaracji onFoo
w C
, więc kontynuuje w górę w hierarchii. Kiedy kompilator sprawdza B
, widzi, że na tym poziomie znajduje się deklaracja void onFoo(int i)
, więc przestaje wyszukiwać i próbuje rozwiązać problem przeciążenia. W tej chwili nie można rozwiązać problemu z przeciążeniem ze względu na niespójność argumentów.
Fakt, że deklaracja void onFoo(int)
występuje w B
poziomie skutkuje ukrywanie resztę przeciążenia w dowolnej klasy podstawy, jak zatrzyma odnośnika. Zauważ, że jest to problem z niewykwalifikowanym wyszukiwaniem, funkcja jest nadal dostępna i ma zastosowanie do obiektu, ale nie zostanie znaleziona przez regularne wyszukiwanie (nadal możesz ją nazwać c->A::onFoo()
).
W jaki sposób radzić sobie z ukrywanie, najprostszym sposobem jest zatrudnienie deklarację korzystając przynieść funkcje w zakresie:
class B : A {
public:
using A::onFoo; // All A::onFoo overloads are *considered* here
void onFoo(int);
};
Efekt deklaracji using
tutaj jest to, że gdy klasa B
zostaje wyszukany, w poszukiwaniu identyfikatora onFoo
, kompilator jest instruowany, aby uwzględnić wszystkie przeciążenia klasy onFoo
w klasie bazowej, umożliwiając regularne wyszukiwanie w celu znalezienia A::onFoo()
.
+1 - Ładne wyjaśnienie. – Mahesh