Code sparen
-
Hey guyz
Prost neues Jahr erst Mal
!Leider lässt einen die Arbeit auch im neuen Jahr nicht einfach so in Ruhe und deshalb steht bei mir bereits wieder folgendes Problem an:
std::vector<CEMeter> emArray; std::vector<CLPMeter> lpArray; // ... // Read out EMeters for(int i = 0; i < emArray.size(); i++) { bool blInMtrList = true; for(int j = 1; j < argc; j++) { // Check if current meter is in argument list if(strcmp(emArray.at(i).get_strAddress(), argv[j]) == 0) { blInMtrList = true; break; } blInMtrList = false; if(!blInMtrList) { // If current meter is not in list, skip it continue; } for(int j = 0; j < 3 && emArray.at(i).rd_Data() == -2; j++) { // Read out requested meter... sleep((unsigned int) spTmp.get_fTmOut()); } printf(emArray.at(i).get_strDevRep()); // ... and printf response } // Read out LPMeters for(int i = 0; i < lpArray.size(); i++) { bool blInMtrList = true; for(int j = 1; j < argc; j++) { // Check if current meter is in argument list if(strcmp(lpArray.at(i).get_strAddress(), argv[j]) == 0) { blInMtrList = true; break; } blInMtrList = false; } if(!blInMtrList) { // If current meter is not in list, skip it continue; } for(int j = 0; j < 3 && lpArray.at(i).rd_Data() == -2; j++) { // Read out requested meter... sleep((unsigned int) spTmp.get_fTmOut()); } printf(lpArray.at(i).get_strDevRep()); // ... and printf response }Was da in diesem ganzen Code gemacht wird, spielt eigentlich keine Rolle, denn das funktioniert so weit prima
. Viel schlimmer ist: Eigentlich mache ich hier zwei mal genau dasselbe, nur mit unterschiedlichen Klassen. Die beiden Klassen erben zwar von derselben Vaterfunktion, implementieren die hier gebrauchte Funktion 'rd_Data()' aber separat.Gibt es an dieser Stelle eine elegante Variante, Code zu sparen? Die Objekte sollten dabei nicht gecastet werden.
Danke für eure Hilfe und beste Grüsse auch ins neue Jahr
Kessi
-
mach' doch 'ne funktion draus und gib der 'nen pointer auf die basisklasse oder so ähnlich...
:xmas2:
-
Hallo
mach die Methode in der Basisklasse virtuel bzw. abstrakt, und benutze Pointer auf die Basisklasse um Nutzen aus Polymorphie zu ziehen.
bis bald
akari
-
Ok, das mit der abstrakten Methode ist sicher nicht schlecht, das habe ich bereits 'mal eingebaut
.Allerdings ist mein Problem ja, dass ich 2 unterschiedliche Vektoren habe:
std::vector<CEMeter> emArray; std::vector<CLPMeter> lpArray;Ich kann ja unterschiedliche Objekte nicht in denselben Vektor packen. Also müsste ich in der Schleife 'mal den einen und 'mal den anderen Vektor verwenden
. Auch wenn ich das ganze in eine Funktion packen würde, müsste ich derselben einen Vektor mitgeben, den sie verwenden soll. Dabei sind die unterschiedlichen Vektortypen 'std::vector<CEMeter>' und 'std::vector<CLPMeter> ' erneut nicht austauschbar...Und da bleibe ich jetzt irgendwie stecken
...
-
Hallo
die Schleife must du schon jeweils extra ausführen. Aber alles was in der Schleife ist, kannst du in eine Funktion auslagern, die als Argument einen Pointer auf die Basisklasse entgegennimmt. Dann brauchts du in der konkreten Schleife diese Funktion nur mit der Adresse des aktuellen Arrayelements aufzurufen.
Wenn du die Polymorphie ganz nutzen willst, müßtest du zwei Vektoren mit dem Elementtyp Pointer auf Basisklasse nehmen. Dann wärst du zwar selber für die Speicherverwaltung der Objektinstanzen zuständig, aber könntest eine Funktion schreiben, die so einen vector entgegennimmt und auch die Schleife selbständig abartbeiten kann.
bis bald
akari
-
Also das einzige was mir hier in den Sinn kommt ist die Verwendung eines Funktionstemplates
template<typename T> void ReadOut(std::vector<T> & arr, char const * argv, int argc) { for(int i = 0; i < arr.size(); i++) { bool blInMtrList = true; for(int j = 1; j < argc; j++) { // Check if current meter is in argument list if(strcmp(arr.at(i).get_strAddress(), argv[j]) == 0) { blInMtrList = true; break; } blInMtrList = false; } if(!blInMtrList) { // If current meter is not in list, skip it continue; } for(int j = 0; j < 3 && arr.at(i).rd_Data() == -2; j++) { // Read out requested meter... sleep((unsigned int) spTmp.get_fTmOut()); } printf(arr.at(i).get_strDevRep()); // ... and printf response } }BR
Vinzenz
-
evilissimo schrieb:
Also das einzige was mir hier in den Sinn kommt ist die Verwendung eines Funktionstemplates
Genau das war auch mein Gedanke und die Schleife mit 'blInMtrList' sollte man durch ein find ersetzen können:
template<typename T> void ReadOut(std::vector<T> & arr, char const * argv, int argc /*, spTmp */ ) { for(int i = 0; i < arr.size(); i++) { if( find( argv, argv + argc, std::string( arr.at(i).get_strAddress() ) ) != argv + argc ) { // If current meter is in list ... for(int j = 0; j < 3 && arr.at(i).rd_Data() == -2; j++) { // Read out requested meter... sleep((unsigned int) spTmp.get_fTmOut()); } printf(arr.at(i).get_strDevRep()); // ... and printf response } } }Dann wird's doch richtig übersichtlich

Gruß
Werner
-
Ok, das sieht ja richtig interessant aus. Besonders der 'find' lässt mich ja ziemlich alt aussehen
.Allerdings eine Frage: Ich habe im Moment eine separate Klasse, wo alle Ausgaben erledigt werden. Elegant wäre es nun, wenn ich diese Funktion dort hinein nehmen könnte. Muss ich dazu nun der gesamten Klasse ein Typentemplate mitgeben oder kann ich das irgendwie auf diese einzige Funktion beschränken?
Thx auf jeden Fall und Greeetz
Kessi
-
KessiMC schrieb:
Ok, das sieht ja richtig interessant aus. Besonders der 'find' lässt mich ja ziemlich alt aussehen
.Allerdings eine Frage: Ich habe im Moment eine separate Klasse, wo alle Ausgaben erledigt werden. Elegant wäre es nun, wenn ich diese Funktion dort hinein nehmen könnte. Muss ich dazu nun der gesamten Klasse ein Typentemplate mitgeben oder kann ich das irgendwie auf diese einzige Funktion beschränken?
Thx auf jeden Fall und Greeetz
KessiHi,
es ist möglich das du das einfach als Methodentemplate verwendest.
Sprich innerhalb der Klasse. Die ganze Klasse muss deswegen dann nicht zum Template mutieren

BR
Vinzenz
-
kkk, dann versuch' ich das doch einfach 'mal
.Thx @all und greeetz
Kessi