Template-Klasse "Minimum" gibt nicht das richtige Minimum aus (gerundetes int statt double in der Ausgabe)



  • Hallo,
    ich habe hier eine Übungsaufgabe, bei der ich aus einer gegebenen Klasse Minimum, die aus den Werten eines int-Arrays das Minimum ausgibt, eine Template-Klasse machen soll, die aus sämtliche Typen das Minimum ausgibt.
    Leider wird bei meiner Lösung ein int, nämlich 1 ausgegeben, obwohl sich diese Zahl nicht in meinem double-Array befindet. Ich weiß leider nicht mehr weiter, da ich absoluter Anfänger bin.

    #include <iostream>
    
    using namespace std;
    
    
    template <typename T>
    class Minimum {
    private:
      T *array;
      int length;
    public:
      Minimum(T *parray, int plength) {
        array = parray;
        length = plength;
      };
    
      int berechne_minimum() {
        T min = array[0];
        for(int i=1; i<length; ++i) {
          if (array[i] < min) min = array[i];
        }
      return min;
      }
    };
    
    int main() {
      double werte[] = {1.3, 1.5, 1.1, 1.4};
      int length = 4;
      double min;
      Minimum<double>* my_minimum = new Minimum<double>(werte, length);
      min = my_minimum->berechne_minimum();
      cout << "Minimum: " << min << endl;
    
      return 0;
    }
    
    

    Ich freue mich über jede Hilfe, dankeschön 🙂



  • Guck dir den Rückgabetype der berechne_minimum Funktion an.

    Möchtest du noch mehr Feedback? Spoiler: Da wartet ne Menge Arbeit.

    Edit:
    Das Erzeugen des Objektes auf dem Heap in der Form ist ein absolutes no-go. Selbst in deinem Mini Beispiel erzeugst du schon ein Memory Leak.
    Erstens besteht da überhaupt keine Notwendigkeit, und zweitens: Wenn man schon Objekte auf dem Heap erzeugt, dann sollten sie in einen smart pointer verpackt werden, es sei denn, es sprechen echte Gründe dagegen (was in 99.99% aller Fälle nicht der Fall ist).



  • Oh vielen Dank! 🙂 Ich hab mir den Code heute tausend Mal angesehen und das nie gesehen.



  • zum Edit:
    Tatsächlich war die Aufgabe in der Form gegeben, dass der Code ziemlich genauso aussah und die Klasse statt des Template-typs einen Int-Typ hatte und man das nur umwandeln sollte.
    Ist natürlich schade, wenn so ne Aufgabe nicht sinnvoll dargestellt ist, aber vielen Dank.



  • @veki Wie lautet denn die Aufgabe im Wortlaut?



  • @veki

    Lebenszeit von Objekten ist ein großes Thema in C++, gerade als Neueinsteiger ist es manchmal schwierig, die Probleme zu erkennen. C++ vergibt da auch keine Fehler und kompiliert anstandslos, aber zur Laufzeit fliegt dir deine Anwendung dann um die Ohren. Dein Code ist in mehreren Fällen problematisch.

    1. keine Überprüfung auf Gültigkeit der Daten ( array kann null sein, arraylänge kann 0 sein, beides führt zu Speicherzugriffsfehlern in Zeile 18)
    2. const-correctness nicht umgesetzt: Deine Klasse braucht nur-Lesezugriff auf die Daten, daher ist T const* besser als T*
    3. Gefahr eines dangling Pointers (die Daten, auf die der Pointer zeigt, existieren nicht mehr)
      Beispiel:
    template<typename T>
    class Minimum
    {
       T* Data_;
        std::size_t Length_;
    public:
       Minimum( T* data, std::size_t length ) :
          Data_( data ), Length_( length )
       {
       }
       
       T berechne_minimum()
       {
          ...
          return retval;
       }
    };
    
    template<typename T>
    Minimum<T> create_minimum_calc()
    {
       int data[] = { 1, 3, 5, 7 };
       return Minimum<int>( data, 4 );
    }
    
    int main()
    {
       Minimum<int> mc = create_minimum_calc();
       int boom = mc.berechne_minimum();
    }   
    


  • @Schlangenmensch

    "a)
    Hier soll die gewönliche Klasse Minimum auf die Verwendung von Templates umgestellt werden:
    • Ein Objekt der Klasse Minimum wird mit einem int-Array sowie dessen Länge initialisiert.
    • Die Methode berechne_minimum gibt den kleinsten Wert aus dem Array zurück.

    Im Folgenden ist eine Implementation von Minimum inklusive main-Funktion mit beispielhafter Anwen-
    dung zu finden."

    [...Code wie beschrieben...]

    "Implementieren Sie die Klasse Minimum neu als Klassen-Template, sodass das Array von einem beliebi-
    gen Zahlen-Typ (z.B. double, int usw.) sein kann."



  • @veki

    Schick den Aufgabensteller mal hier vorbei 😉



  • @DocShoe Danke, das ist echt hilfreich für später

    Die wissen das wahrscheinlich selbst (hoffe ich :D), aber machen dann so Pups-Aufgabe weils den nur um die Template Geschichte geht (ist halt ne Klausuraufgabe, für die nicht viel Zeit bemessen wird)



  • Ich glaube nicht 🙂

    Wenn man das richtig machen wollte wäre man bei sowas, mit weniger Overhead und potenziellen Fallstricken:

    template<typename T>
    T const* minimum( T const* first, T const* last )
    {
        T const* retval = nullptr;
        if( last != first  )
        {
          retval = first++;
          for( ;first != last; ++first )
          {
             if( *first < *retval )
             {
                retval = first;
             }
          }
       }
       return retval;
    }
    
    int main()
    {
       int data[] = { 11, 9, 3, 5, 7 };
       int const* min = minimum( data, data +5 );
    }
    

    Und dann ist man auch schon bei std::min_element aus der STL.



  • Und in dem Beispiel Code kommt tatsächlich ein new vor, aber keine delete

    Ansonsten, eine Beispielimplementierung für eine Minimum Funktion hat @DocShoe ja schon gegeben. Heute würde man vlt auch noch eine Überladung für eine Range anbieten, aber der ist mithilfe der einen Funktion ja dann schon fast fertig.

    Aber vlt ist das ja der steinige Weg hin zu solchen generischen Funktionen (die Hoffnung stirbt zuletzt).


Anmelden zum Antworten