2010-12-16 13 views
10

Wie kann ich erzwingen, dass eine Basisklassenmethode nicht von einer abgeleiteten Klasse überschrieben wird?Wie kann verhindert werden, dass eine Methode in der abgeleiteten Klasse überschrieben wird?

+5

nicht Zwing es virtuell in der Basisklasse? Dann kann es nicht überschrieben, nur überladen werden. Es gibt kein direktes Äquivalent zu Javas "finalen" Methoden, wenn das die Frage ist. –

+0

also ohne Verwendung eines virtuellen Schlüsselwortes können wir es nicht machen, also wie haben sie in JAVA dann implementiert – sriks

+0

in Java, Kennzeichnung eine Methode 'final' verbietet Unterklassen von der Implementierung dieser Methode, und der Compiler und/oder Byte-Code-Verifikator wird dies erzwingen . In C++ gibt es keine Möglichkeit, es zu verbieten, es ist nur so, dass per Definition von "override" nur virtuelle Funktionen "überschrieben" werden können. –

Antwort

14

Wenn Sie die Methode nicht virtuell machen, können abgeleitete Klassen die Methode nicht überschreiben. Eine Klasse kann jedoch eine Methode aus einer Basisklasse nicht überschreiben und außerdem verhindern, dass weitere abgeleitete Klassen die gleiche Methode überschreiben (). Sobald die Methode virtuell ist, bleibt sie virtuell.

+1

+1: Der Teil jedoch war der Schlüssel für mich. – imallett

+4

mit C++ 11 können Sie final Specifier verwenden, um zu vermeiden, dass eine Methode in abgeleiteten Klassen überschrieben wird – tharinduwijewardane

1

gut, wenn Sie es öffentlich halten möchten, deklarieren Sie es nicht virtuell.

BEARBEITEN: Srikanth kommentierte Fragen über das Überschreiben einer privaten Elementfunktion in einer abgeleiteten Klasse.

class A 
{ 
public: 
    virtual ~A(){}; 
    void test() 
    { 
     foo(); 
    }; 
private: 
    virtual void foo() 
    { 
     std::cout << "A"; 
    }; 
}; 


class B : public A 
{ 
public: 
    virtual void foo() 
    { 
     std::cout << "B"; 
    }; 
}; 


void test() 
{ 
    B b; 
    A& a = b; 

    a.test(); // this calls the derived B::foo() 

    return 0; 
}` 
+3

Abgeleitete Klassen können weiterhin virtuelle private Memberfunktionen überschreiben. –

+0

Ich habe bearbeitet, danke für die Korrektur. –

+0

aber wie können wir eine private Methode überschreiben, ohne die abgeleiteten einen Freund oder die Zugriffsspezifizierer – sriks

2

Machen Sie es nicht virtuell.

Dies verhindert nicht, von Ihrer Klasse abzuleiten und die Funktion zu verbergen (indem eine andere Mitgliedsfunktion mit demselben Namen bereitgestellt wird). Wenn Ihre Klasse jedoch nicht dazu bestimmt ist, abgeleitet zu werden (kein virtueller Destruktor, keine virtuellen Memberfunktionen), sollte das kein Problem darstellen.

-1

Kurze Antwort: Es gibt keine Notwendigkeit dafür. Lange Antwort können Sie some twists tun, aber ist es das wert?

18

Wenn Sie den Spezifizierer final aus C++ 11 verwenden können, können Sie verhindern, dass abgeleitete Klassen diese Methode überschreiben. (Microsoft-Compiler erscheinen die ähnliche sealed mit ähnlichen Semantik zu unterstützen.)

Hier ist ein Beispiel:

#include <iostream> 

struct base { 
    // To derived class' developers: Thou shalt not override this method 
    virtual void work() final { 
     pre_work(); 
     do_work(); 
     post_work(); 
    } 
    virtual void pre_work() {}; 
    virtual void do_work() = 0; 
    virtual void post_work() {}; 
}; 

struct derived : public base { 
    // this should trigger an error: 
    void work() { 
     std::cout << "doing derived work\n"; 
    } 
    void do_work() { 
     std::cout << "doing something really very important\n"; 
    } 
}; 

int main() { 
    derived d; 
    d.work(); 
    base& b = d; 
    b.work(); 
} 

Hier ist, was ich bekomme, wenn ich versuche, es zu kompilieren:

$ g++ test.cc -std=c++11 
test.cc:17:14: error: virtual function ‘virtual void derived::work()’ 
test.cc:5:22: error: overriding final function ‘virtual void base::work()’ 
+0

Frage: Warum sollte ich "work()" als "virtuell" deklarieren, wenn ich nicht möchte, dass es in abgeleiteten Klassen überschrieben wird - warum nicht einfach als endgültig markieren? – Sonic78

+0

@ Sonic78 Gute Frage!In realem Code haben Sie möglicherweise eine andere Basisklasse namens "base", die eine virtuelle Funktion bereitstellt, die in Klassen, die von Ihrer Zwischenbasis stammen, nicht überschrieben werden soll. – moooeeeep

Verwandte Themen