Warum ruft p->fn2()
die abgeleitete Klassenfunktion auf, obwohl fn2
in D
privat ist?
Zugriffsmodifikatoren wie public
, private
und protected
werden nur beim Kompilieren erzwungen. Wenn Sie die Funktion über einen Zeiger auf die Basisklasse aufrufen, weiß der Compiler nicht, dass der Zeiger auf eine Instanz der abgeleiteten Klasse verweist. Nach den Regeln, die der Compiler aus diesem Ausdruck ableiten kann, ist dieser Aufruf gültig.
Es ist normalerweise ein semantischer Fehler, um die Sichtbarkeit eines Members in einer abgeleiteten Klasse zu reduzieren. Moderne Programmiersprachen wie Java und C # lehnen es ab, solchen Code zu kompilieren, da auf einen Member, der in der Basisklasse sichtbar ist, in der abgeleiteten Klasse immer über einen Basiszeiger zugegriffen werden kann.
Der Aufruf p->fn2()
wird zur Laufzeit ausgewertet, abhängig vom Typ des beanstandeten Objekts, auf den p
zeigt. Zur Kompilierzeit sieht die Kompilierung den Aufruf p->fn2()
als Aufruf an B::fn2()
und da B::fn2()
öffentlich ist, meldet der Compiler nicht nur Fehler. Nur zur Laufzeit wird der tatsächliche Funktionsaufruf D::fn2()
ausgewertet.
Dies bricht das Encapsulation
-Prinzip nicht. Dies ist eine Funktion von C ++ namens Run-time Polymorphism
oder Dynamic Polymorphism
Von wikipedia :
In OOP, wenn eine abgeleitete Klasse ein a erbt Basisklasse, ein Objekt des Abgeleiteten Klasse kann als (oder Cast) bezeichnet werden entweder der Basisklasse Typ oder der abgeleitete Klassentyp Wenn es gibt Basisklassenmethoden, die von der abgeleitete Klasse, der Methodenaufruf Verhalten ist mehrdeutig.
Die Unterscheidung zwischen virtuell und Nicht-virtuell löst diese Mehrdeutigkeit. Wenn die fragliche Funktion ist in der Basisklasse als "virtual" bezeichnet dann die Funktion der abgeleiteten Klasse würde genannt werden (wenn es existiert). Wenn es ist nicht virtuell, die Basisklasse Funktion würde aufgerufen werden.
HTH.
Tags und Links c++ inheritance polymorphism access-modifiers