2013-03-16 11 views
5

Mein C++ Code ist wie folgt:Kann ich nur eine Methode in Erben überschreiben?

#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; 
} 

während der Kompilierung ich:

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 

Wenn ich Überschreibung nach B f (int) verwenden versucht, ich den gleichen Fehler habe.

Ist es in C++ möglich, nur eine Methode zu überschreiben? Ich habe nach einem Codebeispiel mit override gesucht, das auf meinem Computer kompiliert wird und noch keinen gefunden hat.

+0

möglich Duplikat von [Virtuelle Methode verursacht Kompilierungsfehler in der abgeleiteten Klasse] (http://stackoverflow.com/questions/7274723/virtual-method-causes-compilation-error-in-derived-class) –

+1

Nein, sorry, Das war ein anderes Problem. –

+0

mögliches Duplikat von [C++: Begründung hinter der Regel] (http://stackoverflow.com/questions/4837399/c-rationale-behind-hiding-rule) – Angew

Antwort

5

Sie überschreiben den Namen "f" als Methodenname. So wird auch jede Überladung außer Kraft gesetzt.

Sie konnten die using Schlüsselwort, verwenden Sie einfach den Compiler zu sagen, an der Basisklasse als gut aussehen:

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

Das Problem ist, dass die virtuelle Funktion f() in Klasse BA ‚s nicht-virtuelle Überlastung mit einem identischen Namen verbirgt. Sie können eine using Erklärung verwenden sie in Umfang zu bringen:

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

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

Ja, es ist möglich, nur eine Methode einer Klasse außer Kraft zu setzen, es virtuell zu machen. Nicht virtuelles wird beschattet, wenn es in einer geerbten Klasse deklariert wird.

4

Sie gebissen durch, wie Namen-Suche funktioniert in C++. Der Compiler durchsucht aufeinanderfolgende Bereiche, bis ein Bereich mit mindestens einem Objekt mit einem übereinstimmenden Namen gefunden wird.

Angenommen, das Element ist eine Funktion, dann wird die Auflösung unter den Funktionen mit dem Namen, den es in diesem Bereich gefunden hat, überladen. Wenn keiner von denen funktioniert, tut es nicht Suche weiter Bereiche, um eine bessere Passform zu finden.

Sie können jedoch bekommen es die Eltern-Klasse in diesem Fall zu suchen:

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

Auf den ersten Blick könnte es scheinen, dass die using Aussage Mehrdeutigkeit erzeugen konnte. Zum Beispiel mit dem using A::f; gibt es jetzt zweif(int) Funktionen im Bereich B (A::f(int) und B::f(int)) sichtbar.C++ hat einige Regeln, um dies ebenfalls zu berücksichtigen. Wenn Sie beispielsweise (b.f(3);) in main (mit der using A::f;) hinzufügen, werden Sie immer noch keine Zweideutigkeiten bekommen - es ruft b::f(int) auf, wie Sie es erwarten würden.

Verwandte Themen