Funktion für die Nutzung der Methode ToString() in verschiedenen Klassen.
-
Moin,
ich möchte eine Funktion schreiben, welche allgemein von Klassen die ToString Funktion nutzt. Es gibt also Klassen C1, C2, C3, etc. welche eine Funktion ToString() definiert haben und wie folgt definiert sind:
class C1{ private: std::string NameVar; /*Der Rest der Klasse ist stets unterschiedlich*/ public: std::string ToString(){return NameVar;} void DefineName(const std::string fName, void* objArr, int nObj){this->NameVar = GetNextName(fName, objArr, nObj);} /*Der Rest der Klasse ist stets unterschiedlich*/ }
class C2{ private: std::string NameVar; /*Der Rest der Klasse ist stets unterschiedlich*/ public: std::string ToString(){return NameVar;} void DefineName(const std::string fName, void* objArr, int nObj){this->NameVar = GetNextName(fName, objArr, nObj);} /*Der Rest der Klasse ist stets unterschiedlich*/ }
Ich habe dann einen Stapel mit diesen Objekten. Es gibt also einen Stapel für C1, einen für C2 usw.
Ich möchte vermeiden, dass zwei Objekte in diesem Stapel den gleichen Namen haben. Wenn ein bereits
vorhandener Name gewählt wird, soll dieser automatisch durch <Name_001> ersetzt werden. Wenn Name_001
bereits vorhanden ist, wird dieser eben durch <Name_002> ersetzt usw. Und ich möchte diese Funktion nur einmal
schreiben für alle Klassen.objArr ist der Stapel (Klassisches C-Array) einer beliebigen Klasse, welche die Funktion ToString() besitzt. nObj entspricht der Anzahl der Stapelinhalte.
Meine Frage ist jetzt, wie ich diese Funktion GetNextName schreiben kann.
Das Konzept sieht wie folgt aus:#include <cstring> #include "..\\C1\\CM1_Definition.hpp" #include "..\\C2\\CM2_Definition.hpp" /*include der Definition aller Klassen*/ #ifndef GETNEXTNAME_HPP #define GETNEXTNAME_HPP std::string GetNextName(const std::string fName, void* objArr, int nObj) { std::string DummyName = fName; bool NamePresent = false; do { for (int i = 0; i < nObj; i++) { if (objArr.ToString() == DummyName) { /*Error here, because type is not known*/ IncrementName(DummyName); } } } while(NamePresent); } std::string IncrementName(std::string fName); /*Funktion passt den bereits vorhandenen Namen an indem es _001 anhängt oder ein vorhandenes _001 in ein _002 umwandelt*/ #endif
Ich hoffe, ich habe das Problem klar beschrieben.
Vielen Dank im Voraus.
-
@CJens sagte in Funktion für die Nutzung der Methode ToString() in verschiedenen Klassen.:
objArr ist der Stapel (Klassisches C-Array) einer beliebigen Klasse, welche die Funktion ToString() besitzt
Ein klassisches C-Array kann keine Funktionen besitzen. Zeigst du mal dessen Definition?
Da du den Tag templatefunktio(n) benutzt, nehme ich an, daß du gerne hierfür ein Template erstellen möchtest, oder?
Die Alternative wäre selbstverständlich eine gemeinsame Basisklasse für die Klassen C1, C2, ... zu benutzen.
-
Hi.
Vielleicht habe ich mich da unklar ausgedrückt. Das C-Array soll ja die Klassen an sich beinhalten, welche die Funktion ToString() als Methode besitzen. Der Code könnte dann so aussehen:
int main() { C1* pC1 = (C1*)malloc(5 * sizeof(C1)); C2* pC2 = (C2*)malloc(5 * sizeof(C2)); for (int i = 0; i < 5; i++) { pC1[i].DefineName("Default Mesh", pC1, 5); pC2[i].DefineName("Default Family", pC2, 5); } for (int i = 0; i < 5; i++) { std::cout << pC1[i].ToString().c_str() << std::endl; std::cout << pC2[i].ToString().c_str() << std::endl << std::endl; } /*Erwartete Ausgabe: Default Mesh Default Family Default Mesh_001 Default Family_001 Default Mesh_002 Default Family_002 Default Mesh_003 Default Family_003 Default Mesh_004 Default Family_004 */ return 0; }
Ich weiß nicht, ob man das über ein Template macht. Ich wage mich zu erinnern, dass ich so etwas vor Jahren schon mal ohne Templates gemacht habe.
Ich möchte an dieser Stelle deutlich machen, dass ich bewusst auf <vector> verzichte, da das hier eine DLL werden soll, auf welche ich über Interop mit C# zugreifen möchte. Das Marshalen wäre mir dann zu kompliziert... aber das ist ja ein anderes Thema.
-
Irgendwie muß die Funktion aber den Datentyp kennen, denn auf
void
-Objekten kannst du keine Funktionen ausführen.Also entweder
std::string GetNextName<T>(const std::string fName, T* objArr, int nObj) { // ... for (int i = 0; i < nObj; i++) if (objArr[i].ToString() == DummyName) }
oder eben per (abstrakter) Basisklasse (und diese dann als Parameter angeben).
Ich finde es aber kein gutes Design, daß in den Klassenfunktionen von C1, C2, .. auf das äußere Array zugegriffen wird.
-
Ok, danke - ich werde es dann über ein Template versuchen.
Ich finde dieses Design auch nicht gut, aber die Klasse kann ja nicht wissen, in welchem Stapel sie sich befindet. Es gibt nämlich mehrere Stapel, da diese wiederum ein Teil einer anderen Klasse sind. vielleicht kann man es damit noch eingrenzen - ändert aber nichts an diesem spezifischen Problem.
Vielen Dank.