Ist es möglich, eine Funktion in der C ++ - Kindklasse zu überschreiben, ohne ein virtuelles Schlüsselwort für die Funktion in der Elternklasse zu verwenden, die abstrakt ist?

7
%Vor%

Ist das in C ++ möglich? Ich überschreibe func1() , das NICHT virtuell ist und bereits eine Definition in der abstrakten Elternklasse hat.

    
codeLover 08.03.2012, 15:24
quelle

5 Antworten

19

[Angenommen, Child erweitert Parent , anders als der Code-Snap zeigt]

Ja, es ist möglich [es heißt Verstecken] - aber Sie werden kein dynamisches Verhalten erhalten.

Der statische Typ definiert, welche Methode aufgerufen wird und nicht der dynamische Typ.

Zum Beispiel:

%Vor%

Ruft Parent::func1() auf
während:

%Vor%

Ruft Child::func1()

auf     
amit 08.03.2012, 15:26
quelle
3

Nein, es ist nicht möglich, die Definition im übergeordneten Element zu überschreiben (zumindest in Bezug auf C ++ ist "überschreiben" normalerweise speziell auf virtuelle Funktionen beschränkt). Stattdessen wird durch das Definieren einer Funktion mit demselben Namen in der Kindklasse die Funktion im übergeordneten Element mit demselben Namen verborgen (dh im Kontext eines untergeordneten Objekts wird nur nach diesem Namen gesucht) die Funktion im Kind, nicht die im Elternteil).

Wenn Sie wollen (und die Funktionen haben unterschiedliche Signaturen), können Sie auch die Funktionen im Eltern- und im Kind als überladen behandeln lassen, so dass ein Anruf versucht, den jeweils besseren Treffer aufzurufen:

%Vor%

Jetzt bekommst du:

%Vor%

Dies ist jedoch noch eine dritte Art von Verhalten, die sich von einer virtuellen Funktion oder unterscheidet, die eine Funktion in dem Kind hat, die die eine im Elternteil verbirgt.

Bei einer virtuellen Funktion basiert die Auswahl der aufgerufenen Funktion auf dem dynamischen Typ. Wenn Sie also einen Zeiger / Verweis auf die Basisklasse haben, hängt die aufgerufene Funktion davon ab, ob sich diese auf ein Objekt der Basis bezieht abgeleitete Klasse.

Wenn Sie die Funktion ausblenden, basiert die aufgerufene Funktion auf dem statischen Typ. Wenn Sie sie also über einen Zeiger / Verweis auf die Basis aufrufen, ruft sie die Basisfunktion auf, auch wenn sie sich auf ein Objekt der Funktion bezieht abgeleitete Klasse. Wenn Sie jedoch einen Zeiger oder eine Referenz auf die abgeleitete Klasse verwenden (oder direkt eine Instanz davon verwenden), ruft sie die Funktion in der abgeleiteten Klasse auf.

Mit der using -Anweisung erhalten Sie eine Funktionsüberladung. Wenn Sie also die Funktion (im Kontext der abgeleiteten Klasse) aufrufen, basiert die aufgerufene Funktion darauf, welche Signatur der Funktion am besten zu den Parametern passt. Sie übergeben.

    
Jerry Coffin 08.03.2012 15:36
quelle
2

Sie können überladen , wenn sie unterschiedliche Argumenttypen haben.

Sie können verbergen es in dem hier gezeigten Sinne, so dass Child::func1 anstelle von Parent::func1 im Code aufgerufen wird, der weiß, dass es sich um eine Kind-Instanz handelt. Amit weist jedoch darauf hin, dass Sie keinen dynamischen Versand erhalten.

%Vor% %Vor%     
Useless 08.03.2012 15:32
quelle
0

Ja, das ist gültige C ++ - Syntax und definiert ein Child :: func1, das Parent :: func1 in Child versteckt.

Dies bedeutet jedoch nicht, dass es Child :: Parent :: func1 vollständig ersetzt. Diese Funktion kann weiterhin explizit für ein Element von child aufgerufen werden.

%Vor%

Auch diese Funktion wird nicht virtuell sein. Also, das Folgende ..

%Vor%

ruft Parent :: func1 und nicht Child :: func1 auf.

    
Agentlien 08.03.2012 15:35
quelle
0

Das meiste wurde gesagt.

Deine Erwartungen wären richtig, wenn du über Java redest. In Java könnte jede nicht-private, nicht-finale Methode außer Kraft gesetzt werden. Vielleicht kennen Sie eine andere Programmiersprache als C ++

Übrigens sind in Ihrem Code zwei Dinge falsch

  • " class " muss in Kleinbuchstaben geschrieben werden
  • Der Standardzugriff von Mitgliedern in der Klasse ist " privat ". Es ist NICHT erlaubt, private Member, die nicht rein sind, außer Kraft zu setzen.
stefan bachert 08.03.2012 15:40
quelle