Warum ist Subtyping auch direkt für Objekte erlaubt???
-
1. long long gibt es in Pornos und C99 aber nicht in c++

2. Das Objekt der abgeleiteten Klasse wird zurechgestutzt.
In c++ funktioniert die Polymorphie über Zeiger und Referenzen, d.h. es ist möglich ein Objekt der abgeleiteten Klasse an eine Referenz der Basisklasse zu binden.
Es werden daher der Copy-Konstruktor und der Zuweisungsoperator der Basisklasse verwendet, die du selbst definiert hast bzw. der Compiler definiert hat.
3. Im Konstruktor von Zahlbox2 initialisiert du die Basisklasse nicht, d.h. du gibst dem Basisklassen-i keinen speziellen Wert, daher kommen auch unterschiedliche Zahlen heraus.
P.S.: Du kannst der Basisklasse natürlich auch spezielle Konstruktoren bzw. Zuweisungsoperatoren verpassen, die Objekte der abgeleiteten Klassen akzeptieren, dann wird es allerdings schwierig mit dem Zugriff auf die Member.
-
Mitleid schrieb:
1. long long gibt es in Pornos und C99 aber nicht in c++


-
Danke für deine Antwort......
....also das Objekt der Basisklasse wird zurechtgestutzt.OK.
Hab jetzt parallel auch gelesen dass die Vererbung über anonyme Basisklassenobjekte realisiert ist.Ich versuch mir das nur grad intern vorzustellen-->Vielleicht kommt das zurechtstuzen dann daher das bei Zuweisung an den SuperklassenTyp einer Klasse die nächstinnere Klasse kopiert wird , die Äußere(abgeleitete) Klasse fällt weg...dass würde dann auch die undef. Ausgabe der Werte erklären ,denn wenn ich die Variable in der
(umgebenden) abgeleiteten Klasse überschreibe würde das gleichnamige Attribut in der (inneren)Basisklasse ja nicht initialisiert und bleibt undefiniert, außer ich mach das explizit über den scope-Operator...Könnt ich das so etwa sehn oder is das falsch ,(würde sich ja in den Auswirkungen auch irgendwie mit den in der letzten Antwort beschrieben decken(stutzen..))??????????????????
Warum ist Subtyping-Polymorphie in C++ für die ! Objekte selber ! dann überhaupt zugelassen ? Gibt ja auf Objekten eh nie Sinn,weil von spezielleren Objekten alles abgeschnitten wird.Wär doch viel besser Subtyping nur für Zeiger auf Typen
einer Klassenhirarchie zu erlauben , oder fällt jemandem ein Grund ein, weswegen es sinvoll war , das bei der
Entwicklung von C++ auch für Objekte selber zu erlauben????
Naja.......aber vielleicht kann man ja doch was Tolles damit machen und es hat seine Berechtigung , und ich komm nur nich drauf........
-
Bitte gewöhn dir ganz schnell ab das "subtyping" zu nennen, denn das sagt keiner und versteht auch keiner (ohne weitere Erklärungen).
Was du in deinem Posting als Code-Beispiel zeigst nennt man Slicing, und es ist in C++ erlaubt, weil es nunmal erlaubt ist (weil es sich aus den Regeln für Konvertierung zwischen Referenz-Typen so ergibt).
Und je mehr Fragezeichen und/oder Rufzeichen du an einen Satz dranschreibst... naja, das muss ich jetzt nicht erklären.
-
@JohnnyDoe
Ich muss hustbaer Recht geben. Es fällt etwas schwer zu begreifen, was du eigentlich meinst, z.B. mit "Subtyping-Polymorphie für die ! Objekte selber !"Also Nochmal. Du musst dir das nicht so vorstellem, dass bei einer Zuweisung sozusagen der Teil des Speicherbereiches, in welchem das Basisklassen-Objekt liegt 1:1 kopiert wird.
Für folgende Zuweisungen bzw. Initialisierungen
ZF[0] = Zahlbox2(123456789123456789123456789LL); //Zuweisungsoperator ZF[2] = FZahlbox2(123456789123456789123456789LL); //.. Zahlbox2 x; Zahlbox1 y = x; //Copy-Konstruktorsind Zuweisungsoperator bzw. Copy-Konstruktor der Basisklasse verantwortlich. Es werden also Funktionen aufgerufen.
Diese sehen so aus
class Zahlbox1{ public: Zahlbox1(){;} Zahlbox1(int in):i(in){;} Zahlbox1(const Zahlbox1&); // Copy-Konstruktor Zahlbox1 &operator=(const Zahlbox1&); //Zuweisungsoperator int i; };Und nur weil die Funktionen eine Referenz der Basisklasse erwarten, an die auch Objekte der abgeleiteten Klasse gebunden werden können funktioniert das überhaupt. D.h. es findet ein Typumwandlung statt und das resultierende Objekt hat mit Zahlbox2 nichts mehr zu tun.
-
Mitleid schrieb:
123456789123456789123456789LLOptimist

-
Ok. Ich denke das hat mir schon ziemlich weiter geholfen.
Versteh das jetz so : Für Zusammengesetzte Datentypen wie Klasse muss ich selber definieren wie das Objekt intern kopiert wird.Sowohl der Zuweisungsoperator der,falls nicht selbst implementiert, vom System erzeugt wird ,als auch analog der CopyKonstruktor nehmen beide standartmäßig Referenzen der entsprechenden Typen zu denen Sie gehören und weil Subtyping basierend auf Adressen bei zusammengestzten Typen ja problemlos funktioniert nehmen die beiden Funktionen also auch Objekte des Subtyps.Ein übergebenes Objekt wird also bei Bedarf in eine Referenz eines SuperTyps verwandelt ,diese zeigt auf das interne anonyme SuperklassenObjekt , welches das abegleitet Objekt besitzt.Damit sind in der Funtion nur Attribute des Supertyps zugreifbar.Diese werden dann bei (vom Compiler auto-generierten) Zuweisungsop.funtion oder Copykonstruktorfunktion wie gewünscht kopiert.
Demnach gibts dann auch kein Sybtyping direkt auf den Objekten wie ich erst dachte,weil bei zusammenges. Typen alles intern über Referenzen läuft.Nur bei den Basistypen wird bitweise kopiert.Und die undefinerte Ausgabe die ich hatte leigt dann einfach daran , das das entsprechende Attribut des anonymen internen Superklassenobjekts nicht initialisiert wurde,letzteres wegen des gleichen verwendeten Namens für das Attribut(Überschreibung) in der(äußeren)Subklasse .
Könnt ichs jetz vielleicht irgendwie verstanden haben

-
Jup, klingt gut. Bis auf den vorletzten Satz. Es macht nichts, dass die Attribute denselben Namen haben. Die abgeleitete Klasse ist für die Initialisierung der Basisklasse und somit für den Aufruf des Basisklassenkonstruktors verantwortlich. Wenn du da nicht explizit etwas angibst, wird der Standard-Konstruktor der Basisklasse (der dann auf jeden Fall existiert) verwendet und dementsprechend sieht dann das Objekt aus.
Übrigens, da du ja bereits mit Java Erfahrung hast, sollte man vielleicht noch bemerken, dass das auch nur funktioniert wenn Zahlbox2 ein "ist ein" Verhältnis zu Zahlbox1 hat. Also, technisch gesprochen, eine public-Vererbung stattfindet.
Zahlbox2 : public Zahlbox1{};Willst du die Schnittstelle der Basisklasse nicht mehr zur Verfünung stellen, indem du z.B. private oder protectet vererbst
Zahlbox2 : private Zahlbox1{};dann ist eine Zuweisung bzw. Initialisierung eines Zahlbox1-Objektes mit einem Zahlbox2-Objekt auch nicht mehr möglich.
Tolle Sache.

@hustbaer
Ja, hätte vielleicht mehr darauf achten sollen, was ich da kopiere. Wenigstens habe ich den "Wiedererkennungswert" für den Threadstarter hochgehalten.
-
Bevor ich zerfleischt werden korrigiere ich meinen Satz von
... mit einem Zahlbox2-Objekt auch nicht mehr möglich.
in
... mit einem Zahlbox2-Objekt so auch nicht mehr möglich.
Mit der erwähnten Methode der Zahlbox1-Klasse Konstruktor und Zuweisungsoperator zu verpassen, die Zahlbox2-Referenzen erwarten geht es dann natürlich wieder (eingeschränkt).
-
Ok, klar hängt die Init. der Basisklasse noch vom Basisklassenkonstruktor ab,is C++ ja diesbezüglich was Subtyping,Vererbung ,Kapselung und die Aufrufreihenfolge bei Objekterzeugung angeht Java scheinbar recht ähnlich.(Obwohl es wahrscheinlich eigentlich heißen müsste Java ist C++ ähnlich).Bei dem Zahl-Zeugs von mir sind die Werte also dann undefiniert , weil der default-Konstrukter der Basisklasse der implizit im Konstruktor der Subklasse aufgerufen auch nix anderes vorsieht ,weil er ja nicht überschrieben wurde.!??Hab ich das ungefähr richtig verstanden?Das mit dem private-Konstruktor und dem dadurch abgestellten Subtyping ist gut(sollte ja in Java auch funktionieren,denke zumindest sowas mal gelesen zu haben). Wenn ich hobbymäßig mal was in Java für mich "programmiert" hab hab ich Vererbung vorallem dann eingesetzt wenn es darum ging von vorhandenen Klassen zu erben z.B. bei der GUI usw. Hab halt selten irgendwelche spezielleren Features genutzt die man mit Modifiern bei Vererbung konstruieren kann,obwohl ich mich am Anfang irgendwann mal damit auseinander gesetzt hatte.
Irgendwie ergibt sich schon wieder eine Frage : Ist Vererbung in C++ (nur weil in dem Buch aus dem ich lerne öfters von einem internen anonymen Basisklassenobjekt die Rede ist) tatsächlich über ein generiertes Member-Superklassen-Objekt und Delegation and dieses ,was irgendwelche Methodenaufrufe für die man den vollqualifizierenden Namen nicht mehr angeben muss angeht, realisiert ? Wie sieht das Ganze intern aus bzw. was davon ist auf SICHTBAREN Code abbildbar? Danke überigens für die bisherigen Antworten und eure Zeit.Glaube so lernt C++ sich echt effektiver als allein, vorallem weil sich keine falschen oberflächlichen Sichtweisen einprägen die wahrscheinlich ab und an zu Fehlern führen könnten.
-
JohnnyDoe schrieb:
Hab ich das ungefähr richtig verstanden?
Ich denke schon.

JohnnyDoe schrieb:
Wie sieht das Ganze intern aus bzw. was davon ist auf SICHTBAREN Code abbildbar?
Die Implemtierung des c++-Standards ist selbst nicht standardisiert. Da ist also vieles denkbar. D.h. man kann ohne Informationen des Herstellers gar nicht sagen, was unter der Haube eigentlich passiert.
In der Praxis dürfte jedoch alles ziemlich nahe an Stroustrups Modell sein. Dort werden die nichtstatischen Member eines Objekts zusammen mit den eventuell vorhandenen Zeigern auf sog. "Virtual Tables" in einem Speicherbereich zusammengesetzt. Innerhalb dieses Bereichs kann dann direkt adressiert werden (über ein Offset).
Der Speicherbereich eines Objekts der abgeleiteten Klasse enthält dann die Member aus der Basisklasse und daran angehängt, die Member, die durch die abgeleitete Klasse zusätzlich definiert werden. Je nachdem, wie deine Klassenhierarchie aussieht (Mehrfachverbung, virtuelle Funktionen) sind dann noch keiner, einer oder mehrere dieser Zeiger auf die jeweilige Virtual Table dabei. Es wird ebenfalls direkt adressiert.
Nur die virtuelle Basisklasse bei der virtuellen Vererbung bildet da ein Ausnahme. Auf die muss indirekt zugegriffen werden. Da gibt es dann auch wieder verschiedene Möglichkeiten das zu realisieren.
Das ist aber alles nicht in 3 oder 4 Worten erklärt. Vor allem die Vor- und Nachteile einer bestimmten Vorgehensweise. Ich kenne dummerweise auch kein Tutorial oder Link in welchem man sich schnell eine Übersicht verschaffen könnte. Vielleicht hilft einer der Kollegen aus.
Oder du gibst dir die entsprechende Literatur. Lippman hat da ein ganzes Buch dazu geschrieben und das eine oder andere Paper zu dem Thema geistert wohl auch herum. Wie gesagt, vielleicht kennt ein anderer Forenteilnehmer eine gute Quelle.