Exception-cast..? [solved]

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
joggel

Exception-cast..? [solved]

Beitrag von joggel »

Hi ho,

ich spiele gerade etwas rum, und zwar mit exceptions.
Ich habe folgenden Code (Ich will mal nicht jede Klasse aufschreiben, ich versuche aussagekräftige Namen zu nehmen) :

Code: Alles auswählen

try
{
 throw ExceptionXYZ_DerivedFromExceptionBase(arg1,arg2,arg3); 
}
catch( ExceptionBase& exception ) // <== "ExceptionXYZ_DerivedFromExceptionBase" wird ja hier auf jeden Fall "gefangen"
{
 ExceptionXYZ_DerivedFromExceptionBase* exceptionXYZ( dynamic_cast<ExceptionXYZ_DerivedFromExceptionBase*>(&exception ) );
// der Cast funktioniert hier nicht!!
}
Genau... ich möchte gerne herausfinden, welcher Typ die Exception war. Ich könnte auch ein "catch" für jeden Exception-Typ schreiben, aber das will ich mal bewusst vermeiden.
Was mir spontan einfällt:
Einen eigenen cast schreiben, der anhand des Klassennamens prüft, ob der Cast funktioniert.
Allerdings stehe ich da wieder vor einem Problem:
Ich muss so oder so einen cast durchführen.
Mal etwas Code:

Code: Alles auswählen

T  my_dynamic_cast<T>( ExceptionBase* exception)
{
	if( T.getClassName() == exception->getClassName() )
	{
	  // hier müsste irgendetwas passieren, was aus "exception" eine Instanz von "T" macht, und zurueckgegeben wird
	}
}
Ist halt alles nur mal etwas rumgespiele und ich weiß auch garnicht, ob ich dabei alles richtig mache...
Zuletzt geändert von joggel am 14.02.2012, 10:25, insgesamt 1-mal geändert.
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: Exception-cast..?

Beitrag von RazorX »

Der dynamic_cast prüft die Polymorphie über die virtual tables. Wenn du also keine virtuelle Funktion durch die Hierarchie reichst, wird dynamic_cast immer nullptr zurückgeben.
joggel

Re: Exception-cast..?

Beitrag von joggel »

Ok... das erklärt es.
Aber kann ich das irgendwie umgehen?
Also das ich doch auf irgendeinen Weg an den Typ und Informationen der gewurfenen Exception rankomme?
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: Exception-cast..?

Beitrag von RazorX »

AFAIK hast du in C++ nur die Möglichkeit über dynamic_cast + viruelle Methoden die Polymorphie zu überprüfen. Das Problem ist einfach, dass C++ keine Typüberwachung mitbringt, also im Speicher nicht drinsteht was für ein Typ das ist (wie z.B. in C#, Java). Du kannst natürlich sowas mit Klassennamen machen, ob es jedoch sinnvoller ist als stumpf eine virtuelle Methode zu definieren ist fragwürdig.
joggel

Re: Exception-cast..?

Beitrag von joggel »

Mh... ok.
Das ist mistig... ich könnte zwar rausbekommen, um welche abgeleitete Klasse es sich handelt, aber an die konkreten Funktionen und Member der abgeleiteten Klasse komme ich nicht ran... verdammt!
Oder nur durch irgendwelche schrägen Umwege.
Naja, mal sehen was mir einfällt oder auch nicht ^^
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: Exception-cast..?

Beitrag von RazorX »

Naja so schwer ist das aber doch nicht.

Code: Alles auswählen

// Klassen 
class Foo : std::exception {
public:
    virtual ~Foo();
};

class Bar : public Foo{
public:
    virtual ~Bar();
};

// In der Methode
try {
   throw Foo();
} catch(std::exception& e) {
   Foo* myException = dynamic_cast<Foo*>(&e);
   if(myException != nullptr) {
        // Irgendwas
   } else {
        // Weitere Fälle
   }
}
joggel

Re: Exception-cast..?

Beitrag von joggel »

Das funktioniert bei dir?
Bei mir funktioniert das nicht... deswegen hatte ich ja gefragt.
Ich benutze VS 2005 ( ja, noch kam ich nicht dazu umzusteigen! ).
Benutzeravatar
Schrompf
Moderator
Beiträge: 4884
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Exception-cast..?

Beitrag von Schrompf »

Eigentlich müsste es wirklich reichen, den Destruktor der Basisklasse virtuell zu deklarieren. Das wäre dann die virtuelle Methode, weswegen der Compiler einen vtable anlegen müsste, womit dynamic_cast dann funktionieren sollte.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: Exception-cast..?

Beitrag von RazorX »

Jo, kleiner Fehler. Muss natürlich von std::exception public erben^^

Das funktioniert, habs getestet:

Code: Alles auswählen

#include "stdafx.h"
#include <exception>
#include <iostream>

class Foo : public std::exception {
public:
	virtual ~Foo(){}
};

class Bar : public Foo{
public:
	virtual ~Bar(){}
};

// In der Methode
int _tmain(int argc, _TCHAR* argv[])
{
	try {
	   throw Foo();
	} catch(std::exception& e) {
	   Foo* myException = dynamic_cast<Foo*>(&e);
	   if(myException != nullptr) {
		   std::cout << "Foo" << std::endl;
	   } else {
			// Weitere Fälle
	   }
	}
	system("PAUSE");
	return 0;
}
Edit: nullptr ist ein neues Sprachfeature, stattdessen kannste natürlich NULL oder einfach 0 verwenden.
joggel

Re: Exception-cast..?

Beitrag von joggel »

Oh, stimmt!
Gerade getestet.
Es funktioniert, sehr schön: danke!! :)
Hatte den Destructor nicht als virtual deklariert.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Exception-cast..? [solved]

Beitrag von dot »

joggel hat geschrieben:Genau... ich möchte gerne herausfinden, welcher Typ die Exception war. Ich könnte auch ein "catch" für jeden Exception-Typ schreiben, aber das will ich mal bewusst vermeiden.
Wieso? Genau das wäre imo die saubere Lösung.
joggel

Re: Exception-cast..? [solved]

Beitrag von joggel »

dot hat geschrieben: Wieso? Genau das wäre imo die saubere Lösung.
Ja, das mache ich eigentlich auch immer so.
Aber mir ging es diesmal um was anderes und wollte mal was testen.
Und habe dabei einfach bei meinen Test-Klassen keine virtuellen Funktionen deklariert...
deswegen funktionierte der Cast nicht, und ich dachte, dass das mit den Casts bei Exception irgendwie anders läuft.
Also: Unwissenheit/Unachtsamkeit.
Antworten