2013-03-16 5 views
5

Il mio codice C++ è il seguente:Posso eseguire l'override di un solo metodo in ereditarietà?

#include<iostream> 
using namespace std; 

class A 
{ 
    public: 
     virtual void f(int i) 
     { 
      cout << "A's f(int)!" << endl; 
     } 
     void f(int i, int j) 
     { 
      cout << "A's f(int, int)!" << endl; 
     } 
}; 

class B : public A 
{ 
    public: 
     virtual void f(int i) 
     { 
      cout << "B's f(int)!" << endl; 
     } 
}; 

int main() 
{ 
    B b; 
    b.f(1,2); 
    return 0; 
} 

durante la compilazione ottengo:

g++ -std=c++11 file.cpp 
file.cpp: In function ‘int main()’: 
file.cpp:29:9: error: no matching function for call to ‘B::f(int, int)’ 
file.cpp:29:9: note: candidate is: 
file.cpp:20:16: note: virtual void B::f(int) 
file.cpp:20:16: note: candidate expects 1 argument, 2 provided 

Quando ho provato ad usare esclusione dopo f di B (int), ho ottenuto lo stesso errore.

E 'possibile in C++ sovrascrivere solo 1 metodo? Ho cercato un esempio di codice usando override che verrà compilato sulla mia macchina e non ne ho ancora trovato uno.

+0

possibile duplicato di [metodo virtuale causa errore di compilazione nella classe derivata] (http://stackoverflow.com/questions/7274723/virtual-method-causes-compilation-error-in-derived-class) –

+1

No, mi dispiace, quello era un altro problema. –

+0

possibile duplicato di [C++: logica dietro la regola nascosta] (http://stackoverflow.com/questions/4837399/c-rationale-behind-hiding-rule) – Angew

risposta

5

Si sta sovrascrivendo il nome "f" come nome del metodo. Quindi qualsiasi sovraccarico verrà sovrascritto.

è possibile utilizzare la parola chiave using, solo per dire al compilatore di guardare la classe di base così:

class B : public A 
{ 
    public: 
     using A::f; 
     virtual void f(int i) 
     { 
      cout << "B's f(int)!" << endl; 
     } 
}; 
10

Il problema è che la vostra funzione virtuale f() in classe BnascondeA s' sovraccarico non virtuale con un nome identico. È possibile utilizzare una dichiarazione using per portarlo in ambito:

class B : public A 
{ 
    public: 
     using A::f; 
    // ^^^^^^^^^^^ 

     virtual void f(int i) 
     { 
      cout << "B's f(int)!" << endl; 
     } 
}; 
0

Sì, è possibile eseguire l'override solo un metodo di una classe, rendono virtuale. Non virtuale verrà ombreggiato quando dichiarato in una classe ereditata.

4

Sei stato morso da come nome di ricerca funziona in C++. Il compilatore cerca tra gli ambiti successivi finché trova un ambito con almeno un elemento con un nome corrispondente.

Supponendo che l'elemento sia una funzione, esegue quindi la risoluzione di sovraccarico tra le funzioni con quel nome che ha trovato in tale ambito. Se nessuno di questi funziona, lo standard non continua a cercare più ambiti per trovare una soluzione migliore.

È possibile, tuttavia, farlo per cercare di classe dei genitori, in questo caso:

class B : public A 
{ 
    public: 
     using A::f; 
     virtual void f(int i) 
     { 
      cout << "B's f(int)!" << endl; 
     } 
}; 

A prima vista, potrebbe sembrare che la dichiarazione using potrebbe produrre ambiguità. Ad esempio, con il using A::f; ora ci sono due f(int) funzioni visibili portata B s'(A::f(int) e B::f(int)).C++ ha alcune regole per coprire anche questo, quindi se si aggiunge (ad esempio) b.f(3); in main (con il using A::f; in posizione) non si otterrà ancora l'ambiguità - chiamerà b::f(int) come ci si aspetterebbe.

Problemi correlati