🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: de.comp.lang.c++
4 messages
4 total messages Started by Haiko Emmel Mon, 04 Dec 1995 20:31
casting-Probleme mit virtueller Vererbung
#951
Author: Haiko Emmel
Date: Mon, 04 Dec 1995 20:31
55 lines
1422 bytes
Hallo,

ich bin heute auf folgendes casting-Problem gestossen:


// Uebersetzt mit Borland C++ 3.1

class Base
{
public:
	char base() const { return('b'); }
};

class Meddle : virtual public Base
{
public:
	char meddle() const { return('m'); }
};

class Medium : virtual public Base
{
public:
	char medium() const { return('M'); }
};

class Top : public Meddle, public Medium
{
public:
	char top() const { return('t'); }
};


main()
{
	Base* bPtr;
	Medium* mPtr;
	Meddle* MPtr;
	Top* tPtr;

	tPtr=new Top();
	bPtr=(Base*) tPtr;		// funktioniert!
	mPtr=(Medium*) bPtr;		// can not cast Base * to Medium *
	MPtr=(Meddle*) bPtr;		// can not cast Base * to Meddle *
	delete(tPtr);

}

Mich wundert es, dass der Compiler da nicht casten kann. Wenn man von
der Basisklasse base nicht virtuelle erbt, klappt es mit dem casting!
Ist das nun ein Borland-Problem, oder geht das in C++ prinzipiell
nicht, oder gibt es einen Trick, wie man das trotzdem hinbekommt?

Wer weiss Rat?

Haiko Emmel
Re: casting-Probleme mit virtueller Vererbung
#947
Author: Harald Fuchs
Date: Tue, 05 Dec 1995 11:33
19 lines
1597 bytes
100321.1321@compuserve.com (Haiko Emmel) writes:

> 	tPtr=new Top();
> 	bPtr=(Base*) tPtr;		// funktioniert!
> 	mPtr=(Medium*) bPtr;		// can not cast Base * to Medium *
> 	MPtr=(Meddle*) bPtr;		// can not cast Base * to Meddle *
> 	delete(tPtr);

> }

> Mich wundert es, dass der Compiler da nicht casten kann. Wenn man von
> der Basisklasse base nicht virtuelle erbt, klappt es mit dem casting!
> Ist das nun ein Borland-Problem, oder geht das in C++ prinzipiell
> nicht, oder gibt es einen Trick, wie man das trotzdem hinbekommt?

Das ist explizit verboten, weil es die Implementierung erleichtert
(keine Backpointer von base auf derived nötig).  Im allgemeinen ist
eine derartige Notwendigkeit ohnehin ein Hinweis auf einen
Designfehler.
Re: casting-Probleme mit virtueller Vererbung
#965
Author: Karl-Heinz Krause
Date: Tue, 05 Dec 1995 16:23
79 lines
2601 bytes
Am 4. Dez. 1995 schrieb Haiko Emmel (100321.1321@compuserve.com):

> Hallo,

> ich bin heute auf folgendes casting-Problem gestossen:

> // Uebersetzt mit Borland C++ 3.1

> class Base
> {
> public:
> 	char base() const { return('b'); }
> };

> class Meddle : virtual public Base
> {
> public:
> 	char meddle() const { return('m'); }
> };

> class Medium : virtual public Base
> {
> public:
> 	char medium() const { return('M'); }
> };

> class Top : public Meddle, public Medium
> {
> public:
> 	char top() const { return('t'); }
> };

> main()
> {
> 	Base* bPtr;
> 	Medium* mPtr;
> 	Meddle* MPtr;
> 	Top* tPtr;

> 	tPtr=new Top();
> 	bPtr=(Base*) tPtr;		// funktioniert!

Hier reicht "bPtr=tPtr;". Die Umwandlung in einen Zeiger auf eine
Basisklasse geht automatisch. Da Casting immer eine problematische Sache
ist, sollte man auf das Hinschreiben redundanter Castings verzichten.

> 	mPtr=(Medium*) bPtr;		// can not cast Base * to Medium *
> 	MPtr=(Meddle*) bPtr;		// can not cast Base * to Meddle *
> 	delete(tPtr);

> }

> Mich wundert es, dass der Compiler da nicht casten kann. Wenn man von
> der Basisklasse base nicht virtuelle erbt, klappt es mit dem casting!
> Ist das nun ein Borland-Problem, oder geht das in C++ prinzipiell
> nicht, oder gibt es einen Trick, wie man das trotzdem hinbekommt?

Da gibt es nichts zu wundern, das entspricht genau den Regeln von C++:
das Casten eines Zeigers in einen spezielleren Typ ist nur bei
nichtvirtueller Vererbung erlaubt.

Um das trotzdem hinzubekommen, gibt es nicht nur einen Trick, sondern
eine höchst offizielle Methode, nämlich

	mPtr = dynamic_cast<Medium*>(bPtr);

Allerding ist dynamic_cast in BC 3.1 noch nicht implementiert -- ein
Compiler-Update wäre also fällig.

Es gibt noch eine weitere Einschränkung von dynamic_cast: Die Klasse,
von der gecastet wird, muß polymorph sein, d. h. mindestens eine
virtuelle Funktion oder einen virtuellen Destruktor enthalten. Deshalb
sollte man in den public-Bereich von Base noch folgendes hinzufügen:

	virtual ~Base() {}



Karl-Heinz Krause
Re: casting-Probleme mit virtueller Vererbung
#1012
Author: Karl-Heinz Krause
Date: Thu, 14 Dec 1995 17:17
25 lines
1174 bytes
Am 9. Dez. 1995 schrieb erack@bnb.dinet.com:

> moin Haiko,

> am 04. Dezember 95 schrieb Haiko Emmel an All:

>  HE> tPtr=new Top();
>  HE> bPtr=(Base*) tPtr;// funktioniert!
>  HE> mPtr=(Medium*) bPtr;// can not cast Base * to Medium *
>  HE> MPtr=(Meddle*) bPtr;// can not cast Base * to Meddle *

> mit Top-Down casting geht's:

> mPtr=(Medium*) tPtr;
> MPtr=(Meddle*) tPtr;

Das ist trivial und war nicht die Frage. Im übrigen sind "Top-Down
Castings" unnötig. Man kann und sollte schreiben

	mPtr = tPtr;
	MPtr = tPtr;



Karl-Heinz Krause
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads