In C ++ ist eine Funktion automatisch virtuelle wenn es eine virtuelle Funktion überschreibt?

StackOverflow https://stackoverflow.com/questions/1404797

  •  05-07-2019
  •  | 
  •  

Frage

Ich würde erwarten, dass, wenn foo in Klasse D deklariert, aber nicht virtuell markiert, dann würde der folgende Code die Implementierung von foo in D nennen (unabhängig vom dynamischen Typ von d).

D& d = ...;
d.foo();

Doch in dem folgende Programm, das ist nicht der Fall. Kann das jemand erklären? Ist ein Verfahren automatisch virtuelle wenn es eine virtuelle Funktion überschreibt?

#include <iostream>

using namespace std;

class C {
public:
        virtual void foo() { cout << "C" << endl; }
};

class D : public C {
public:
        void foo() { cout << "D" << endl; }
};

class E : public D {
public:
        void foo() { cout << "E" << endl; }
};

int main(int argc, char **argv)
{
        E& e = *new E;
        D& d = *static_cast<D*>(&e);
        d.foo();
        return 0;
}

Die Ausgabe des obigen Programms ist:

E
War es hilfreich?

Lösung

Standard 10.3.2 (class.virtual) sagt:

  

Wenn eine virtuelle Memberfunktion vf in einer Klasse Basis und in einer Klasse abgeleitet deklariert wird, die direkt oder indirekt aus der Basis, eine Memberfunktion vf mit dem gleichen Namen und die gleichen Parameterliste als Basis :: vf deklariert wird, dann Abgeleitet :: vf ist auch virtuelle (ob es so deklariert wird) und es überschreibt *

     

[Fußnote: Eine Funktion mit dem gleichen Namen, aber eine andere Parameterliste (Klausel über) als virtuelle Funktion nicht notwendigerweise virtuell ist und nicht überschreibt. Die Verwendung des virtuellen Spezifizierer in der Deklaration einer übergeordneten Funktion ist legal, aber redundant (hat leere Semantik). Zutrittskontrolle (Klausel class.access) wird bei der Bestimmung überwiegenden nicht berücksichtigt. --- Ende foonote]

Andere Tipps

Schnelle Antwort kann sein, nein, aber richtige Antwort ist Ja

C ++ nicht weiß, über Funktion versteckt, so überwiegendes virtuelle Funktion ohne virtuelle Schlüsselwort Markierungen, die virtuelle zu funktionieren.

Sie sind keine Kopie des Objekts von e zu schaffen und es in d setzen. So d.foo () folgt normales polymorphes Verhalten und Anrufen abgeleiteten Klasse Methode. Ein Verfahren, das als virtuelle Basisklasse in der erklärt wird, auch in der abgeleiteten Klasse automatisch virtuelles wird.

Die Ausgabe ( „E“) verhält sich genau so, wie man erwarten würde es verhalten.

Der Grund: Die dynamische (d Laufzeit) Typ dieser Referenz E. Sie sind eine statische upcast bis D zu tun, aber das bedeutet nicht den tatsächlichen Typ des Objekts natürlich ändern.

Das ist die Idee hinter virtuellen Methoden und dynamische Versendungen: Sie das Verhalten des Typs sehen Sie wurden instanziieren, die E ist, in diesem Fall

.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top