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
    Kessi

    Hi,

    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


Anmelden zum Antworten