Klasseninstanz über std::vector erzeugen



  • @Th69 sagte in Klasseninstanz über std::vector erzeugen:

    @It0101: Klar, wir packen jedes Pattern in eine Übungsaufgabe!???

    Wir nicht. Aber Anfängern schadet es nicht. Zumal wir hier nicht vom einem aufgezwungenen Parameter-Pack oder einem Funktionstemplate reden, sondern von etwas was man im Grunde häufig braucht und wo etwas Übung nicht schadet.



  • Liebe C++-Lernende. Ihr wendet bitte in Zukunft C++-Programmiertechniken nur noch dann an, wenn die Übungsaufgabe es explizit erfordert oder es von @Th69 oder @wob authorisiert wurde. Auf gar keinen Fall werdet ihr euch außerhalb der exakt passenden Übungsaufgabe mit der Rule-of-Five und anderen Pattern beschäftigen, die zur täglichen Routine gehören sollten. Ausnahmen gibts keine.



  • @It0101 sagte in Klasseninstanz über std::vector erzeugen:

    Ihr wendet bitte in Zukunft C++-Programmiertechniken nur noch dann an, wenn die Übungsaufgabe es explizit erfordert oder es von @Th69 oder @wob authorisiert [sic!] wurde. Auf gar keinen Fall werdet ihr euch außerhalb der exakt passenden Übungsaufgabe mit der Rule-of-Five und anderen Pattern beschäftigen, die zur täglichen Routine gehören sollten. Ausnahmen gibts keine.

    Selten so einen Quatsch gelesen!

    @It0101 sagte in Klasseninstanz über std::vector erzeugen:

    Aber Anfängern schadet es nicht.

    Darüber kann man streiten. Wenn man Anfängern erzählt, dass sie Operatorüberladung auch für ungefähr passende Dinge anwenden sollen und sie die Rule of 5 dort einsetzen lässt, wo sie überhaupt nicht passt, dann kann das durchaus kontraproduktiv sein, weil es nachträglich unter anderem wesentlich schwieriger wird beizubringen, dass eine Klasse nur eine Sache tun soll und nicht hunderte andere Dinge mit übernehmen soll.

    Niemand will verbieten, sich über diese Dinge zu informieren bzw. sich damit zu beschäftigen.



  • @It0101 sagte in Klasseninstanz über std::vector erzeugen:

    [...] sondern von etwas [Rule of 5] was man im Grunde häufig braucht [...]

    So ein Quatsch. Wenn bei Dir das Anwenden der Rule of 5 zur täglichen Routine gehört machst Du irgendwas falsch.



  • @Swordfish sagte in Klasseninstanz über std::vector erzeugen:

    @It0101 sagte in Klasseninstanz über std::vector erzeugen:

    [...] sondern von etwas [Rule of 5] was man im Grunde häufig braucht [...]

    So ein Quatsch. Wenn bei Dir das Anwenden der Rule of 5 zur täglichen Routine gehört machst Du irgendwas falsch.

    Gut häufig ist übertrieben, geb ich zu. Aber jeder sollte sie beherrschen. Mein Ziel ist immer die häufige Verwendung von "= delete" 😁



  • @It0101 Was macht delete eigentlich ?
    bei

    char *ptr = {'A','B','C','D'}; // speicher für 4 char's reserviert 
    delete ptr ;   //speicher leer?
    ptr = NULL; //unvorhergesehene Ereignisse vermeiden  
    

    bin ich da so jetzt richtig ?



  • Das ist nicht kosher. Du darfst delete nur Zeiger füttern, die von new kommen und delete[] Zeiger von new[]. Und natürlich nullptr.



  • ja hab ich eben auch gerade gemerkt . :'D
    Habe auf absenden gedrückt bevor mir eingefallen ist das ich auch einfach versuchen kann.



  • Ich meinte die andere Sorte von delete 😉

    Die Sorte hier, die man braucht wenn man davon überzeugt ist, dass man die Instanzen einer Klasse niemals kopieren oder moven will 😉

    public MyClass
    {
        MyClass();
        ~MyClass() = default;
        MyClass( const MyClass & ) = delete;
        MyClass &operator=( const MyClass & ) = delete;
        MyClass( MyClass && ) = delete;
         MyClass &operator=( MyClass && ) = delete;
    };
    


  • Noch zu der Übungsaufgabe von It0101:
    Ich fand das gut und habe es zur Übung mal in einem Fenster realisiert.
    Vielleicht mal für die Vollständigkeit hier mein Lösungsvirschlag:

    Das ist jetzt nut die mainwindow.cpp Datei:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <math.h>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        connect(ui->pushButton, SIGNAL(clicked()), SLOT(pbClicked()));
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::pbClicked()
    {
        P1X = ui->lineEdit->text();
        P1Y = ui->lineEdit_2->text();
        P2X = ui->lineEdit_3->text();
        P2Y = ui->lineEdit_4->text();
    
        fP1X = P1X.toFloat();
        fP1Y = P1Y.toFloat();
        fP2X = P2X.toFloat();
        fP2Y = P2Y.toFloat();
    
        float fAbstand = sqrt(pow((fP2X-fP1X),2)+pow((fP2Y-fP1Y),2));
        ui->label_4->setNum(fAbstand);
    }
    


  • Wenn ich dich richtig verstehe, möchtest du eigentlich nur auf die Zeile 30, den Abstand, hinaus?

    Der Ursprung dieses Threads war doch deine Punkt-Klasse. Warum finden wir die hier nicht wieder? Außerdem würde ich dir raten, die Berechnung in eine Funktion auszulagern.

    Also zum Beispiel:

    double abstand(const Punkt &p1, const Punkt &p2) {
       return hier-deine-berechnung;
    }
    

    Es gibt auch noch andere Abstände außer dem euklidischen Abstand. Zum Beispiel den Manhattan-Abstand (siehe Wikipedia).

    Du kannst dir auch einen "Radfahr-Anstrengungs-Abstand" ausdenken, wenn du dir z.B. einen Berg auf deinen Koordinaten modellierst und runterfahren weniger "Abstand" hat als hochfahren.

    Wenn dein Punkt ein Punkt auf der Erde mit Länge und Breite ist, kannst du dort auch mal versuchen (Achtung: viel schwieriger), den Abstand zweier Punkte zu berechnen. Dort gibt es aber auch wieder mindestens 2 sinnvolle Abstände: den direkten Abstand (durch die Erde durch) und den Oberflächenabstand.



  • Die Kritik, dass es von der Punktklasse abschweift ist berechtigt.
    Hab das nochmal ohne Fenster gemacht.
    Die Zeile 30 ist hier tatsächlich nur das Relevante.

    Hier ist nochmal eine bessere Lösung:

    abstand.h:

    #ifndef ABSTAND_H
    #define ABSTAND_H
    
    
    class abstand
    {
    public:
        abstand();
        float berechnen(int x1, int y1, int x2, int y2);
    
    };
    
    #endif // ABSTAND_H
    

    punkt.h:

    #ifndef PUNKT_H
    #define PUNKT_H
    
    class punkt
    {
    private:
        int mx, my;
    
    public:
        punkt();
        void setx(int x);
        void sety(int y);
        int getx();
        int gety();
    
    };
    
    #endif // PUNKT_H
    

    abstand.cpp:

    #include "abstand.h"
    #include <math.h>
    
    abstand::abstand()
    {
    
    }
    
    float abstand::berechnen(int x1, int y1, int x2, int y2)
    {
        float Abstand = sqrt((pow((x2-x1),2)+pow((y2-y1),2)));
        return Abstand;
    }
    

    punkt.cpp:

    #include "punkt.h"
    
    punkt::punkt()
    {
    
    }
    
    void punkt::setx(int x)
    {
        mx = x;
    }
    
    void punkt::sety(int y)
    {
        my = y;
    }
    
    int punkt::getx()
    {
        return mx;
    }
    
    int punkt::gety()
    {
        return my;
    }
    

    main.cpp:

    #include <iostream>
    #include "punkt.h"
    #include "abstand.h"
    
    using namespace std;
    
    int main()
    {
        punkt P1, P2;
    
        cout<<"P1X: ";
        int x1;
        cin>>x1;
        P1.setx(x1);
    
        cout<<"P1Y: ";
        int y1;
        cin>>y1;
        P1.sety(y1);
    
        cout<<"P2X: ";
        int x2;
        cin>>x2;
        P2.setx(x2);
    
        cout<<"P2Y: ";
        int y2;
        cin>>y2;
        P2.sety(y2);
    
        abstand A1;
        cout<<"Der Abstand ist: ";
        cout<<A1.berechnen(P1.getx(), P1.gety(), P2.getx(), P2.gety())<<endl;
    
        return 0;
    }
    


  • @theAnfänger77 sagte in Klasseninstanz über std::vector erzeugen:

    Die Zeile 30 ist hier tatsächlich nur das Relevante.

    Nix für ungut, aber schau' Dir mal die einzige Zeile 30 in den Codedingstis an die Du gepostet hast. Konkrete Fragen sind auch nicht verkehrt für Leute die nicht den ganzen Thread lesen wollen.


  • Mod

    @theAnfänger77 sagte in Klasseninstanz über std::vector erzeugen:

    Hier ist nochmal eine bessere Lösung:

    Besser vielleicht, trotzdem schlecht.

    abstand ist ein absolutes Antipattern. Eine Klasse ohne Datenmember, mit nur einer Funktion, die statisch sein sollte? Vom leer implementierten Konstruktor (ein weiteres Antipattenr) gar nicht zu sprechen. Was du da hast ist ein Namespace, keine Klasse. Aber da es sowieso nur eine Funktion hat, ist es nicht einmal ein Fall für einen Namespace, sondern bloß eine Funktion. Außerdem: Da hast du deine tolle Punktklasse und nutzt sie nicht.

    punkt hat keinerlei Eigenschaften eines Punktes. Das sind zwei beliebige Werte, die irgendwie gesetzt werden können, oder auch nicht. Und auch wieder das Antipattern eines leeren Konstruktors.



  • @Swordfish sagte in Klasseninstanz über std::vector erzeugen:

    So ist es natürlich am elogantesten

    struct punkt
    {
        int x;
        int y;
    };
    

    God damn it.

    Alles was man damit machen möchte kann als freie Funktion implementationiert werden.


Anmelden zum Antworten