Veröffentlicht 6. März 201213 j Hallo leute, wie realisiere ich eine Funktion unterschiedliche Datentypen zurückgeben kann? Um was es sich für einen Datentyp handelt, weiß ich beim Aufruf. Habe es erstmal so probiert: template<typename T> T get_DialogitemByCustomID (std::string strCostumID); template<typename T> T ety::CDialog::get_DialogitemByCustomID(std::string strCostumID) { for(std::list<CDialogitem*>::iterator itDialogitem = m_listDialogitems.begin(); itDialogitem != m_listDialogitems.end(); itDialogitem++) { //Es wird die CustomID des Dialogitems überprüft und wenn sie überein stimmt wird das Dialogitem zurückgegeben if((*itDialogitem)->get_CostumID() == strCostumID) { T bla = (*itDialogitem) return bla; } } return NULL; } aber beim Funktionsaufruf: ety::CButton* p_c_etyButtonMainMenuTmpPointer = m_mapDialogs["MainMenuPad"].get_DialogitemByCustomID<ety::CButton*>("PadStartenButton"); sagt er "Verweis auf nicht aufgelöstes externes Symbol", dass get_DialogitembyCustomID<class ety::CButton*> (...) eben nicht ausformuliert wurde... Wie soll ich es sonst lösen? MfG Artery €dit: Das ist eine memberfunktion von einer Klasse, wenn ich einfach nen Konsolenprojekt anlegen, die funktion über die main packe, klappt es... Bearbeitet 6. März 201213 j von Artery
6. März 201213 j Die Definition eines Funktionstemplates muss dort bekannt sei, wo das Template instanziiert wird. Kurz gesagt heißt das, dass du Templates normalerweise nicht in Header- und Quellcodedatei aufteilst, sondern direkt im Header definierst.
6. März 201213 j Autor Mmmm... okay das funktioniert jetzt. Gibt es aber dennoch eine Möglichkeit das aufzuteilen? Weil ich eigentlich keine Ausformulierungen der Funktionen in den Headern haben möchte. MfG Artery
6. März 201213 j Aufteilen kannst du es nur, wenn du vorher genau weißt, für welche Templateparameter du das Template brauchst. Dann kannst du es nämlich explizit instantiieren. Ich bin allerdings der Meinung, dass du für die einfache Konvertierung zwischen zwei Zeigertypen, die ohnehin implizit konvertierbar sind, gar kein Template brauchst.
7. März 201213 j Autor Also ich habe eine Klasse von der habe ich nun mehrere Klassen abgeleitet. Ich wollte nun eine Funktion die ich aufrufe und dann eben jehnachdem einen Zeiger auf die eine Klasse oder auf die andere usw. zurück kriege ohne ihrgendwie 8 Funktionen dafür zuhaben!
7. März 201213 j Ich verstehe irgendwie das Problem nicht. Du hast eine Klasse / Methode als Template, somit kannst Du doch den Template Parameter eben passend setzen und hast die entsprechende Rückgabe. Falls das nicht ausreichend ist, kannst Du auch für konkrete Templates die Methode noch überladen
7. März 201213 j Autor Ja es funktioniert auch alles wunderbar ich will nur das ausformulierte template nicht in meinem Header stehen haben!
7. März 201213 j mache die Headerdatei und unterhalb setzt zu ein #include <inhalt_deines_templates.hpp>
7. März 201213 j Ich wollte nun eine Funktion die ich aufrufe und dann eben jehnachdem einen Zeiger auf die eine Klasse oder auf die andere usw. zurück kriege ohne ihrgendwie 8 Funktionen dafür zuhaben!Wenn dein Funktionstemplate so funktioniert, wie es da steht, ist CDialogitem* implizit (also ohne Cast) in T konvertierbar. Das erreichst du auch mit einer einzigen Funktion, die CDialogitem* zurückgibt. Und selbst wenn du einen Cast brauchen solltest, kannst du die Funktion einfach zerlegen, in den Such-Teil (der ist immer gleich) und den Typumwandlungs-Teil (nur der hängt von T ab). Und dann wirst du feststellen, dass der Typumwandlungsteil dasselbe tut wie static_cast. Und damit tut's das hier auch: // get_DialogitemByCustomID ist kein Template und gibt CDialogItem* zurück ety::CButton* p = static_cast<ety::CButton*>(m_mapDialogs["bla"].get_DialogitemByCustomID("blubb"));[/code] Ein Template ist hier unnötig, und bläht dein Programm nur sinnlos auf.
10. März 201213 j Autor Ja letztlich geht es auch so das stimmt, aber ich wollte einfach nur eine Funktion aufrufen und nicht noch nen cast davor setzen. Ähm noch dazu eine Frage, wo ist der unterschied zwischen static_cast dynamic_cast und dem cast-operator z.b. (CButton*)MeineVariable ?
12. März 201213 j Ähm noch dazu eine Frage, wo ist der unterschied zwischen static_cast dynamic_cast und dem cast-operator z.b. (CButton*)MeineVariable ?Letzteren hat C++ von C geerbt, daher wird er auch "C-Style-Cast" genannt. Der macht je nach Situation komplett unterschiedliche Dinge, daher hat man in C++ neue Cast-Operatoren eingeführt, die einen klar abgegrenzenten Aufgabenbereich haben. Diese sind static_cast, dynamic_cast, reinterpret_cast und const_cast. static_cast kann beispielsweise von einem Zeiger auf eine Basis- in einen Zeiger auf eine abgeleitete Klasse konvertieren. Dabei wird allerdings nicht geprüft, ob der Zeiger wirklich auf ein Objekt der abgeleiteten Klasse zeigt, der Programmierer muss also wissen, was er tut. Wenn man eine solche Prüfung braucht, kann man dynamic_cast benutzten. Da wird der Typ zur Laufzeit geprüft, und falls er nicht passt, ist das Ergebnis des Cast-Ausdrucks null. Die übermäßige Verwendung von dynamic_cast ist allerdings oft ein Zeichen für schlechtes Design. const_cast kann const und volatile von einem Typ entfernen (oder hinzufügen). reinterpret_cast ist sozusagen der Holzhammer, er wandelt um, indem die Speicherrepräsentation einfach als der neue Typ interpretiert wird. Hier kann der Compiler nichts prüfen, wenn's knallt, ist der Programmierer schuld.
12. März 201213 j Autor Ahh okay... nur wieso ist die Benutzung von dynamic_cast ein Zeichen für schlechtes design? Also was sollte ich dann eher benutzen (CButton*) , static_cast oder dynamic_cast, wenn ich einen Basisklassenzeiger umwandeln will und auch genau weiß worin? MfG Artery
12. März 201213 j Ahh okay... nur wieso ist die Benutzung von dynamic_cast ein Zeichen für schlechtes design?Die übermäßige Verwendung ist oft ein Zeichen für schlechtes Design. Wenn man immer wieder prüfen muss, welchen Typ ein Objekt denn nun wirklich hat, dann meist deswegen, weil eine Vererbungsbeziehung besteht, die eigentlich keine ist, sondern nur der Wiederverwendung von Code dient. Also was sollte ich dann eher benutzen (CButton*) , static_cast oder dynamic_cast, wenn ich einen Basisklassenzeiger umwandeln will und auch genau weiß worin?static_cast.
Erstelle ein Konto oder melde dich an, um einen Kommentar zu schreiben.