Programmieren - alles kontrollieren 4.939 Themen, 20.671 Beiträge

Frage zu Vererbung und Zeiger auf Objekte

Yves3 / 2 Antworten / Flachansicht Nickles

Hallo

Folgender Code brachte mich dazu mal etwas genauer über Verebgung und Zeiger auf Basis- und abgeleitete Objekte nachzudenken:

spElemTemp = (MSXML2::IXMLDOMElementPtr) spNodeTemp;


Meine Interpretation, Gedanken und ein paar Fragen dazu, bitte korrigiert mich, wo ich falsch liege:
Hier wir scheinbar ein Zeiger einer Basisklasse einem Zeiger auf eine abgeleitete Klasse zugewiesen. Per Definition sollte das nicht gehen, deshalb braucht es hier auch einen Cast.
Umgekehrt ist das ja auch ohne Cast zulässig, wieso?
Nach purer "Bauernlogik" passt doch etwas kleines in etwas grosses, nicht aber etwas grosses in etwas kleines... dieser Gedanke scheint aber falsch zu sein.
Was ist ein Zeiger überhaupt genau?
Ein Zeiger zeigt auf einen Speicherbereich, hat aber auch einen Typ, demzufolge zeigt er von Punkt a bis Punkt b im Speicher (je nach Typgrösse). Richtig?
Wenn man das so sieht, würde aber die "Bauernlogik" zutreffen und beim Beispiel oben wäre kein Cast nötig... naütrlich mit dem unschönen Nebeneffekt, dass spElemTemp kein Vollwertiges Elementobjekt ist.
Ist es das hier überhaupt?

Viele Fragen :D. Wäre dankbar, wenn jemand etwas Licht ins Dunkle bringen könnte.
bei Antwort benachrichtigen
Yves3 Andreas42 „Hi! Die Bauernlogik ist eigentlich richtig, nur geht s hier nicht darum Töpfe...“
Optionen

Vielen Dank!
Mir ist das jetzt schon etwas klarer.
Im Moment lese ich noch die entsprechenden Themen dieser Einführung hier durch: http://ladedu.com/cpp/kapitel11

EDIT1: Ich habe jetzt noch etwas herumexperimentiert und bin zum Schluss gekommen, dass folgendes beim Zugriff auf eine abgeleitete Klasse von einer Basisklasse aus möglich bzw. nicht möglich ist:


  • Zugreifen auf überladene Funktionen möglich

  • Zugreifen auf Funktionen mit gleichem Namen aber anderer Anzahl Parameter nicht möglich

  • Zugreifen auf Funktionen, die nur in der abgeleiteten Klasse existieren nicht möglich

  • Verwenden von Membervariablen, die nur in der abgeleiteten Klasse existieren in Funktionen der abgeleiteten Klasse möglich

  • Direktes Verwenden von neuen Membervariablen nicht möglich



EDIT2: Mir wurde das jetzt mal ganz ausführlich erklärt und ich habe jetzt den Durchblick :)

Für die, die s interessiert:

Hier ein Beispielprogramm, das die Problematik ziemlich gut aufzeigt.
Bei der zugelassenen Zuweisung von einem abgeleiteten Objekt an den Zeiger eins Basisobjekts warnt der Compiler, falls man versucht auf ein "neues" Objekt der abgeleiteten Klasse zuzugreifen. Bei dem Beispielprogramm geht es um das Gegenteil davon, wo der Compiler nicht mehr warnt:

#include "shape.h"

int main()
{
shape* Shape1 = new shape(2,3);
Shape1->Zeige();
circle* Circle1 = new circle(3.5f,7,8);
Circle1->Zeige();

shape *s1;
circle *c1;

char *test;

c1 = (circle *) Shape1;
test = (char*) Shape1;

printf("pointer = %ld\n"
"x = %ld\n"
"y = %ld\n"
"radius = %ld\n",
c1,&c1->x,&c1->y,&c1->radius );

printf("circle x = %d\n"
"ptr x = %d\n",
c1->y,
(int)*(test+sizeof(int)));

c1->x = 1;
c1->y = 2;
//c1->radius = 1.0; // Führt zu einem wüsten Crash


delete Shape1;
return 0;
}



Ausgabe:

Shape: X: 2 Y: 3
Shape: X: 7 Y: 8
Circle Radius: 3.500000
pointer = 3483228
x = 3483232
y = 3483236
radius = 3483240
circle y = 3
ptr y = 3

Eine kleine Anmerkung zu Ausgabe: Pointer und x sollten eigentlich die gleiche Adresse haben, das ist aber nur wegen dem Compilerinternem Zeugs nicht so. Trotzdem kann auf y mit einem Offset von 1*sizeof(x) zugegriffen werden.

Wichtig ist also, dass man hier genau weiss, was man macht.
Wie mir gesagt wurde handelt es sich bei dem ursprünglichen Codeausschnitt um ein Template, es ist also nicht so hässlich wie s aussieht :D
Ich werde mir Templates noch genauer anschauen.
bei Antwort benachrichtigen