Klasse B erbt von Klasse A. Kann man ein Objekt A in ein Objekt B umwandeln?
"Typumwandlung von abgeleiteten Klassen" http://www.cpp-entwicklung.de/cpplinux/cpp_main/node4.html#SECTION00472200000000000000 Mhh, dann mache ich das offenbar schon - ich dachte, das Basisobjekt wird durch ein abgeleitetes überschrieben..
1 | class A { |
2 | public:
|
3 | int x; |
4 | A (int x_) : x (x_) {} |
5 | };
|
6 | |
7 | class B : public A { |
8 | public:
|
9 | B (int x_) : A(x_) {} |
10 | };
|
11 | |
12 | B wandeln (const A& a) { |
13 | return { a.x }; |
14 | }
|
15 | |
16 | int main () { |
17 | A einA; |
18 | B einB = wandeln (einA); |
19 | }
|
1 | A* a; |
2 | ...
|
3 | B* b = dynamic_cast<B>(a); |
4 | |
5 | if(b) { |
6 | // a war wirklich ein B
|
7 | } else { |
8 | // a war kein B, downcast ungültig, ergebnis NULL
|
9 | }
|
Klaas schrieb: > Klasse B erbt von Klasse A. > Kann man ein Objekt A in ein Objekt B umwandeln? So eine kurze Frage, und doch könnte man soviel dazu antworten. Wie du siehst, kann die Antwort auch recht kurz, aber ganz unterschiedlich sein, je nachdem, was du hier mit "umwandeln" meinst. Ein Objekt, das kein B ist, kann nicht auf einmal eins werden. In der Hinsicht lautet die Antwort "nein". Wenn du mit "umwandeln" eine Konvertierung im C++-Sinn siehst, kannst du mit einem Konvertierkonstruktor oder einem Konvertieroperator ein neues Objekt erstellen und dabei den Typ konvertieren. Dann lautet die Antwort "ja". Eine dritte Möglichkeit ist Polymorphie, und die meinst du wahrscheinlich, denn nur dort ist die Vererbung relevant. Dabei wandelst du aber nicht ein Objekt A in ein Objekt B um, sondern höchstens eine Referenz oder einen Zeiger auf ein solches Objekt. Mit einem static_cast oder dynamic_cast kannst du dann einen Zeiger auf A, der aber in Wirklichkeit auf ein B zeigt, in einen auf B konvertieren, so dass du darüber auch die Funktionalität von B nutzen kannst.
jgdo schrieb: > dynamic_cast<B>(a); das reicht aber noch nicht. Compatibility note: This type of dynamic_cast requires Run-Time Type Information (RTTI) to keep track of dynamic types. Some compilers support this feature as an option which is disabled by default. This needs to be enabled for runtime type checking using dynamic_cast to work properly with these types.
Klaas schrieb: > "Typumwandlung von abgeleiteten Klassen" > http://www.cpp-entwicklung.de/cpplinux/cpp_main/node4.html#SECTION00472200000000000000 > > Mhh, dann mache ich das offenbar schon - ich dachte, das Basisobjekt > wird durch ein abgeleitetes überschrieben.. Welchen Teil von der Beschreibung im Link hast du nicht verstanden?
1 | class A |
2 | {
|
3 | };
|
4 | |
5 | class B : public A |
6 | {
|
7 | };
|
da B von A abgeleitet ist, ist es trivial, dass man überall dort, wo ein A Objekt erwartet wird auch ein B Objekt reingeben kann. Denn die Vererbung sagt ja nichts anderes, als das in jedem B Objekt ein A Objekt steckt. Aber umgekehrt gilt das nicht.
1 | class Kfz |
2 | {
|
3 | };
|
4 | |
5 | class Pkw : public Kfz |
6 | {
|
7 | };
|
8 | |
9 | class Lkw : public Kfz |
10 | {
|
11 | };
|
in jedem Pkw steckt ein Kfz. Genauso wie in jedem Lkw ein Kfz steckt. Aber nicht jedes Kfz ist auch ein Pkw. Es könnte genausogut ein Lkw sein (oder irgendeine andere Klasse, die hier noch gar nicht betrachtet wurde, zb ein Motorrad). Du kannst also gefahrlos aus jedem Pkw ein Kfz machen, in dem du aus dem PkW Objekt den Kfz-Anteil rausholst.
1 | Kfz x; |
2 | Pkw a; |
3 | |
4 | x = a; |
Aber du kannst nicht aus einem Kfz so ohne weiteres einen Pkw machen
1 | Kfz x; |
2 | Pkw a; |
3 | |
4 | a = x; // Nope! |
:
Bearbeitet durch User
Peter II schrieb: > jgdo schrieb: >> dynamic_cast<B>(a); > > das reicht aber noch nicht. > > Compatibility note: This type of dynamic_cast requires Run-Time Type > Information (RTTI) to keep track of dynamic types. Some compilers > support this feature as an option which is disabled by default. This > needs to be enabled for runtime type checking using dynamic_cast to work > properly with these types. Ich wüßte jetzt nicht, welcher Compiler das per Default ausschaltet, oder wozu er das macht. Bei gcc ist es per Default an, da es auch ein grundlegendes Feature der Sprache ist. Was allerdings Voraussetzung ist: Die Basisklasse muss mindestens eine virtuelle Memberfunktion haben, damit sie dynamische Typinformationen bekommt.
Klaas schrieb: > Kann man ein Objekt A in ein Objekt B umwandeln? Umwandeln ist sehr Ungenau. Typumwandlung durch casten wurde ja schon diskutiert. Muss es noch dass selbe Objekt sein, oder geht auch ein neues? Wenn es das gleiche Object sein muss, befindet sich ein Beispiel von mir im Anhang, dass geht nur wenn man den Speicher vorher Reserviert und den placement new operator zum Aufrufen des Konstruktors nutzt, und den Copy constructor entsprechend definiert. Wenn es nicht das selbe Object sein muss, reicht es den Copy constructor zu überladen. Beispiel getestet mit: gcc (Gentoo 4.8.3 p1.1, pie-0.5.9) 4.8.3 Befehl: g++ -std=c++11 -Wall -Wextra -Werror -pedantic cv.cpp -o cv
:
Bearbeitet durch User
Oh, danke für die weitere Diskussion, ich war aus dem Problem völlig raus..
Daniel A. schrieb: > Muss es noch dass selbe Objekt sein, oder geht auch ein neues? > Wenn es das gleiche Object sein muss, befindet sich ein Beispiel von mir > im Anhang, dass geht nur wenn man den Speicher vorher Reserviert und den > placement new operator zum Aufrufen des Konstruktors nutzt, und den Copy > constructor entsprechend definiert. Bei aller Hochachtung zu dieser Template-Magie: Typisches Beispiel, wie man mit aktuellem C++ auch noch den bescheuertsten Designfehler an den eigentlichen Grundlagen der Sprache vorbei implementieren kann. Oliver
:
Bearbeitet durch User
Oliver S. schrieb: > Bei aller Hochachtung zu dieser Template-Magie: > > Typisches Beispiel, wie man mit aktuellem C++ auch noch den > bescheuertsten Designfehler an den eigentlichen Grundlagen der Sprache > vorbei implementieren kann. > > Oliver Genau. Das erlebe ich auch immer wieder. Bei meinem letzen Projekt ( bei einem "namhaften" Diensleister aus dem Automotive Bereich) wurde ein junger, einzelner Entwickler mit Schaffung eines GUI Frameworks auf OpenGl Basis beaufragt. Das allein ist schon schlimm genug ;-) Das was er produziert hat war zum Haare raufen. Ich kann mich an ein Klassen Template errinern, die 4(1) Typ Arumente hatte, wo er dann in der Implementierung diese Argumente mit mit static cast in konkrtete Typen umgewandelt hatte. Das er damit total am Sinn von Templates vorbei entwickelt hat wollte er nicht einsehen.... arrogantes A... ;-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.