it-swarm.com.de

C++ überschreibt private reine virtuelle Methode als public

Warum passiert das?

http://coliru.stacked-crooked.com/a/e1376beff0c157a1

class Base{
private:
    virtual void do_run() = 0;
public:
    void run(){
        do_run();
    }
};

class A : public Base {
public:
    // uplift ??
    virtual void do_run() override {}
};


int main()
{
    A a;
    a.do_run();
}

Warum kann ich eine virtuelle PRIVATE -Methode als öffentlich überschreiben?

14
tower120

Gemäß https://en.cppreference.com/w/cpp/language/virtual#In_detail überschreibt die Member-Funktion virtual einer Basis nur den Funktionsnamen, die Parameter, const/volatile-ness und ref-Qualifier. Der Rückgabetyp, der Zugriffsmodifizierer oder andere Dinge, die Sie erwarten könnten, ist egal. 

Die verlinkte Referenz weist auch ausdrücklich darauf hin, dass:

Base :: vf muss nicht sichtbar sein (kann als privat deklariert oder mit privater Vererbung geerbt werden), um überschrieben zu werden.

Nichts, was ich explizit finden kann, gibt mir die Erlaubnis, dies zu tun, aber die Regeln des Überschreibens verhindern dies nicht. Erlaubt durch virtual Funktionen und Funktionen, die den bestehenden überschreiben und diesen Fall nicht zulassen.

Wenn Sie warum fragen, wie die Sprache ist, müssen Sie möglicherweise das Standardisierungskomitee fragen.

15

Dieses Verhalten ist beabsichtigt. Wenn eine Methode virtuell ist, ist sie unabhängig von Zugriffsmodifizierer für abgeleitete Klassen anpassbar.

Siehe hier

11
rawberry

Beachten Sie, dass diese Implementierung die Art und Weise, wie auf die Basisklasse zugegriffen wird, und ein Konstrukt nicht ändert:

Base& b = a;
b.do_run();

wird nicht funktionieren. 

Ich erinnere mich, dass einige Gründe dahinter stehen, die in "Effective C++" von Scott Meyers ausführlicher beschrieben werden. Das praktische Schlüsselmerkmal besteht jedoch darin, diese Flexibilität in die entgegengesetzte Richtung nutzen zu können, um öffentliche Mitglieder der Basisklasse mit privaten Funktionen in einer abgeleiteten Klasse zu überschreiben, die den Client zwingen, die Basisklasse als Schnittstelle zu verwenden, und nicht die direkte Verwendung der Klasse abgeleitete, die eine versteckte Implementierung bleiben sollte.

2
jszpilewski

Warum kann ich PRIVATE virtuelle Methode als öffentlich überschreiben ???

Weil Sie sich die Basismethode ansehen, die privat im falschen Winkel ist. B::do_run als privat bedeutet, "nur Mitglieder und Freunde dieser Klasse können es verwenden". Um abgeleiteten Klassen das Überschreiben zu untersagen, benötigen wir einen separaten Bezeichner, aber wir können ihn einfach nicht virtual machen. Die Klasse A auf einer anderen Seite ermöglicht es jedem, A::do_run() aufzurufen, und es ist Sache der Klasse A des Designers, dies zu entscheiden. Es gibt also keine Erhebung, wie Sie es sehen.

2
Slava

Wenn die Absicht besteht, einen privaten Code für die Basisklasse zu schreiben und um die Möglichkeit des Überschreibens zu verhindern, implementieren Sie die private Funktion in der Basisklasse und erklären sie als final. Andernfalls: Wann sollte jemand private Virtuals verwenden? ISOCPP.ORG FAQ

0
Amit G.