Forum: PC-Programmierung C++ Instanz zu vererbter wandeln?


von Klaas (Gast)


Lesenswert?

Klasse B erbt von Klasse A.
Kann man ein Objekt A in ein Objekt B umwandeln?

von Dr. Sommer (Gast)


Lesenswert?

Ja.

von Klaas (Gast)


Lesenswert?

Oh, Verzeihung bitte: wie?

von Prof. Winter (Gast)


Lesenswert?

Nein.

von Halbtonerhöhter (Gast)


Lesenswert?


von Klaas (Gast)


Lesenswert?

"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..

von Dr. Sommer (Gast)


Lesenswert?

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
}

von jgdo (Gast)


Lesenswert?

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
}

von Rolf M. (rmagnus)


Lesenswert?

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.

von Peter II (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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
von Rolf M. (rmagnus)


Lesenswert?

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.

von Daniel A. (daniel-a)


Angehängte Dateien:

Lesenswert?

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
von Klaas (Gast)


Lesenswert?

Oh, danke für die weitere Diskussion, ich war aus dem Problem völlig 
raus..

von Oliver S. (oliverso)


Lesenswert?

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
von BobbyX (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.