Greifen Sie auf eine abgeleitete private Memberfunktion von einem Basisklassenzeiger auf ein abgeleitetes Objekt zu [duplizieren]

8
%Vor%

Warum ruft p->fn2() die abgeleitete Klassenfunktion auf, obwohl fn2 in D privat ist?

    
balas bellobas 11.05.2011, 09:05
quelle

4 Antworten

5

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.

    
Hosam Aly 11.05.2011 09:12
quelle
0

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

    
Alok Save 11.05.2011 09:13
quelle
0

Wenn Sie p = new D ausführen, zeigt p->__vfptr jetzt auf den Anfang der virtuellen Funktionstabelle von D . Und da dies zur Laufzeit geschieht, kommen Zugriffsbezeichner nicht ins Spiel.

    
Aamir 11.05.2011 09:14
quelle
-2

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.

    
Sriram 11.05.2011 09:14
quelle