[solved] dynam. Bindung kaputt???
-
iko79 schrieb:
allerdings erklärt das noch immer nicht so ganz, dass auch dann nicht korrekt aufgelöst wird wenn die methode NICHT als abstrakt deklariert.
Wenn der Base-Konstruktor ausgeführt wird ist, hast du noch gar kein Derived-Objekt, nur ein Base-Objekt. Der Derived-"Teil" des Objekts wird erst danach konstruiert.
Deswegen ist es ziemlich sinnlos, virtuelle Funktionen im CTor oder DTor aufzurufen. Das wurde hier schon hundertfach durchgekaut. Mich wundert, dass der IBM-Artikel das nicht mal erwähnt.
-
MFK schrieb:
Wenn der Base-Konstruktor ausgeführt wird ist, hast du noch gar kein Derived-Objekt, nur ein Base-Objekt.
das wundert mich insofern, als dass basisklassenkonstruktorer ja rekursiv von den übergeordneten aufgerufen werden und deshalb bereits bekannt ist, um welches objekt es sich handelt. also logisch find ich das ja nicht. wissen muss mans halt.
MFK schrieb:
Deswegen ist es ziemlich sinnlos, virtuelle Funktionen im CTor oder DTor aufzurufen.
okay, das wusst' ich nicht. find ich aber ganzschön gefährlich.
MFK schrieb:
Das wurde hier schon hundertfach durchgekaut.
hab ich nicht gelesen - hier am laufenden zu bleiben bzw. alles zu lesen was man bis zum eintritt ins forum verpasst hat geht einfach nicht

dankedir!
-
iko79 schrieb:
das wundert mich insofern, als dass basisklassenkonstruktorer ja rekursiv von den übergeordneten aufgerufen werden und deshalb bereits bekannt ist, um welches objekt es sich handelt. also logisch find ich das ja nicht. wissen muss mans halt.
Bekannt ja, aber nicht konstruiert. Der Derived-Konstruktor ruft zuerst den Base-Konstruktor auf, bevor irgendwas anderes passiert. In Deinem Base-Konstruktor sind von Derived noch keine Member konstruiert worden, d.h. sie befinden sich alle in undefiniertem Zustand. Viel gravierender: Die Vtable von Derived (sofern bei der gegebenen Architektur vorhanden) ist auch noch nicht angelegt. Es kann also zur Laufzeit rein technisch schon kein Lookup gemacht werden. Rein logisch gesehen reicht aber eigentlich die Begründung "Derived existiert einfach noch nicht".
okay, das wusst' ich nicht. find ich aber ganzschön gefährlich.
Stimmt schon. Der MSVC warnt hier wenigstens oder schmeisst einen Linkerfehler.
-
iko79 schrieb:
das wundert mich insofern, als dass basisklassenkonstruktorer ja rekursiv von den übergeordneten aufgerufen werden und deshalb bereits bekannt ist, um welches objekt es sich handelt.
Diese Information mag vorhanden sein. Das ändert aber nichts daran, dass der Konstruktor von Derived zu diesem Zeitpunk noch nicht ausgeführt wurde.
MFK schrieb:
okay, das wusst' ich nicht. find ich aber ganzschön gefährlich.
Die Alternative ist IMHO gefährlicher: Die Möglichkeit, eine Methode eines noch nicht konstruierten Objekts aufzurufen.
-
MFK schrieb:
...
MFK schrieb:
okay, das wusst' ich nicht. find ich aber ganzschön gefährlich.
Die Alternative ist IMHO gefährlicher: Die Möglichkeit, eine Methode eines noch nicht konstruierten Objekts aufzurufen.
Hi,
wie macht Java das denn eigentlich ? Die "können" das doch, oder ?
Gruß,
Simon2.
-
C# kanns auch. Wird eben erst die Methodentabelle aufgebaut und dann der Rest konstruiert.
-
Helium schrieb:
C# kanns auch. Wird eben erst die Methodentabelle aufgebaut und dann der Rest konstruiert.
Genauergesagt werden erst Methodentabelle erstellt und Default-Konstruktionen durchgeführt (dazu gehören auch jene, die in der Klasse direkt mit Typ name = wert; aufgeführt sind), dann wird der Basisklassenkonstruktor durchgeführt, dann der eigene. Man kann in dieser Sprache also zumindest nachvollziehen, was zu dem Zeitpunkt definiert ist und was nicht.
-
LordJaxom schrieb:
Helium schrieb:
C# kanns auch. Wird eben erst die Methodentabelle aufgebaut und dann der Rest konstruiert.
Genauergesagt werden erst Methodentabelle erstellt und Default-Konstruktionen durchgeführt (dazu gehören auch jene, die in der Klasse direkt mit Typ name = wert; aufgeführt sind), dann wird der Basisklassenkonstruktor durchgeführt, dann der eigene. Man kann in dieser Sprache also zumindest nachvollziehen, was zu dem Zeitpunkt definiert ist und was nicht.
Ich verstehe das nicht ganz ... es wird IMMER erst ein (ggf. automatischer) Default-Ctor ausgeführt ?
Magst Du das an einem simplen Beispiel mal erläutern ?
Gruß,
Simon2.
-
LordJaxom schrieb:
Helium schrieb:
C# kanns auch. Wird eben erst die Methodentabelle aufgebaut und dann der Rest konstruiert.
Genauergesagt werden erst Methodentabelle erstellt und Default-Konstruktionen durchgeführt (dazu gehören auch jene, die in der Klasse direkt mit Typ name = wert; aufgeführt sind), dann wird der Basisklassenkonstruktor durchgeführt, dann der eigene. Man kann in dieser Sprache also zumindest nachvollziehen, was zu dem Zeitpunkt definiert ist und was nicht.
Ich verstehe das nicht ganz ... es wird IMMER erst ein (ggf. automatischer) Default-Ctor ausgeführt ?
Magst Du das an einem simplen Beispiel mal erläutern ?
Gruß,
Simon2.
-
java ruft immer den standard c-tor der oberklasse auf. wenn du also z.b. sowas hast
class A extends B{ A(){ do(); } do(){} }macht java da implizit ein
class A extends B{ A(){ super(); do(); } do(){} }draus.
-
class B : public A { public: B() : A() { foo(); } void foo() {} };Geht das nicht?
-
Simon2 schrieb:
Ich verstehe das nicht ganz ... es wird IMMER erst ein (ggf. automatischer) Default-Ctor ausgeführt ?
Magst Du das an einem simplen Beispiel mal erläutern ?
Sagen wir es werden IMMER erst alle Objekte Default-Initialisiert. Da Objekte meistens Referenztypen sind heisst das eigentlich nichts weiter als dass die Referenz auf null gesetzt wird. Bei Wertetypen ist es IMHO ein Default (also 0 bei numerischen Typen).
Hier mal ein Beispiel mit Initialisierungsreihenfolge:
public class Derived : Base { private MyRefType m_a; // implizit = null, (1) private List<MyRefType> m_b = new List<MyRefType>(); // explizit, (1) public Derived() // an dieser Stelle ist m_a == null und m_b schon != null und definiert : Base() // muss wie in C++ nur explizit geschehen wenn der Ctor Argumente verlangt, (2) { m_a = new MyRefType(); // (3) } }
-
javatyp schrieb:
java ruft immer den standard c-tor der oberklasse auf.
Das macht C++ auch, wenn du keinen anderen Basis-Ctor in der Initialisierungsliste angegeben hast. Aber das ist auch gar nicht Thema der Frage.
Was würde Java bei so einem Konstrukt ausgeben?
class A { void doit() { print("Basis"); } A() { doit(); } } class B extends A { void doit() { print("Abgeleitet"); } B() {} }(wie oben erkannt wurde, gibt C++ bei dieser Konstellation "Basis" aus, weil im A-Ctor der B-Anteil noch nicht existiert)
-
In C# käme "Abgeleitet" auf den Schirm. Allerdings nur wenn man die Methode in Basis noch virtual markiert.
-
CStoll schrieb:
Was würde Java bei so einem Konstrukt ausgeben?
class A { void doit() { print("Basis"); } A() { doit(); } } class B extends A { void doit() { print("Abgeleitet"); } B() {} }(wie oben erkannt wurde, gibt C++ bei dieser Konstellation "Basis" aus, weil im A-Ctor der B-Anteil noch nicht existiert)
java ruft jeweils die methode doit der instanziierten klasse auf. denn genau wie LordJaxom bereits gesagt hat, erstellt java zunächst alle methodentabellen und ruft erst dann die konstruktoren auf. weshalb sowas wie ein "pure virtual function call" (bzw. abstract in java termen) theoretisch gar nicht auftreten kann.
-
CStoll schrieb:
javatyp schrieb:
java ruft immer den standard c-tor der oberklasse auf.
Das macht C++ auch, wenn du keinen anderen Basis-Ctor in der Initialisierungsliste angegeben hast. Aber das ist auch gar nicht Thema der Frage....
Doch - schon Thema meiner Frage (und damit ein wenig OT - ich hoffe, Ihr verzeiht mir).
@Lord: Danke.
Ja, man hat in Java eigentlich nur Referenzen und primitive Typen in der Hand ... aber wie ist das mit "aggregierten Basisklassen" bei der Vererbung ?Meine Frage ging nämlich eigentlich eher in eine andere Richtung: Was, wenn ich den DefaultCtor "privatisiere", weil das Teil nur über meinen "parametrisierten Ctor" erzeugt werden soll ? Geht das auch (wobei ich dann explizit das passende super() aufrufen muss) ?
Oder bedeutet "default-konstruiert" evtl. nicht unbedingt, dass der "Default-Ctor" aufgerufen wird, sondern eher etwas Ähnliches, was der Compiler für mich macht ?Gruß,
Simon2.
-
Simon2 schrieb:
Meine Frage ging nämlich eigentlich eher in eine andere Richtung: Was, wenn ich den DefaultCtor "privatisiere" [...]
dann schmeisst dir der compiler nen error um die ohren, weil der implizite konstruktor der oberklasse (oder basisklasse, wie man es auch immer nennen mag) nicht sichtbar ist.
-
achso, was aber gehen sollte ist, wenn der erste aufruf im default konstruktor deiner abgeleiteten klassen einen parametrisierten konstruktor der basisklasse aufruft, dann sollte das ganze eigentlich gehen.