2012-06-29 1 views
11

Ich versuche, einen Punkt hier in C++ zu verstehen. Wenn Klasse A eine nicht virtuelle Methode hat und Klasse B, die A erweitert, diese Methode überschreibt, kann ich eine Instanz von B erstellen und irgendwie die in B definierte Methode verwenden? Gibt es einen Punkt, eine nicht-virtuelle Methode zu überschreiben?Kann ich eine Methode verwenden, die eine nicht-virtuelle Methode außer Kraft setzt?

+1

Was Sie beschreiben, heißt * Verbergen *, nicht überschreiben. Schauen Sie sich hier zum Beispiel an: http://stackoverflow.com/questions/2161462/c-inheritance-and-function-overriding – jrok

Antwort

31

Gibt es einen Punkt, eine nicht-virtuelle Methode zu überschreiben?

Sie sind zwingend eigentlich nicht, aber dies ist das Verhalten, das heißt

B* b = new B(); 
A* a = new B(); 
b->method(); //Calls B's method 
a->method(); // Calls A's method 

So bestimmt der Zeiger/Referenztyp die Methode aufgerufen.

Kann ich eine Instanz von B erstellen und irgendwie die in B definierte Methode verwenden?

Ja. Der Zeiger/Referenztyp muss vom Typ B sein (siehe vorheriges Beispiel).

Wenn Sie method nicht erklären virtual zu sein, können Sie nicht Überschreibung es, aber kann man verstecken es.

+0

Große Antwort, danke – Eyal

+1

Ein "Gotcha" ist die Situation, wenn 'A' seinerseits von einer Basisklasse abgeleitet ist (oder eine Schnittstelle implementiert), die 'virtuelle Methode()' deklariert, in diesem Fall 'a-> Methode() 'wird tatsächlich rufen' B.method() '... – BadCash

+0

@Chip Sie haben es versäumt, den Unterschied zu betonen. Diese Antwort ist nur mit BadCashs Kommentar abgeschlossen. – ManuelSchneid3r

9

Wenn B erbt von A, und ein Verfahren in A definiert neu definiert, dann neue Instanzen B nennen B ‚s-Version. Wenn die Methode jedoch nicht virtuell ist, gibt es kein polymorphes Verhalten. Wenn also eine Instanz von B als A referenziert wird, lautet die Methode A. Zum Beispiel:

struct A { 
    void foo() { std::cout << "A::foo" << std::endl; } 
}; 

struct B : public A { 
    void foo() { std::cout << "B::foo" << std::endl; } 
}; 

B b; 
b.foo(); 
A *a = &b; 
a->foo(); 

Der Ausgang des obigen Code wäre:

B::foo 
A::foo 

Wenn jedoch die foo Methode virtueller gewesen war, dann B::foo zweimal gedruckt worden wäre.

+0

Gut geschrieben! :) – niknak

2

Wenn eine Funktion nicht virtual dann bestimmt die Art der Variablen, die Implementierung zu abgesendet wird:

#include <iostream> 

using namespace std; 

struct A { 
    void f() { cout << "A" << endl; } 
}; 

struct B : public A { 
    void f() { cout << "B" << endl; } 
}; 

int main(int args, char** argv) { 

    B b; 
    A& a = b; 

    b.f(); 
    a.f(); 

    return 0; 
} 
0
  • Nein, es gibt keinen Mechanismus ist eine nicht-virtuelle Methode in der Klasse A. außer Kraft zu setzen
  • Ja, können Sie eine nicht-virtuelle Methode aus der Klasse A in B Bereichsauflösungsoperator A überlastet verwenden, indem Sie :: Methoden