std: Klasseninstanzen in std::vector Speichern.



  • Hallo Leute,

    ich bin ein ziemlicher Anfänger und bin auf ein Problem gestoßen, dass ich selbst mit langem Googlen nicht lösen konnte. Ich habe eine Klasse "point" die wie folgt aussieht:

    #pragma once
    #include <vector>
    
    class point
    {
    private:
    	std::vector<double> points_vec; //soll x,y,z variable drin stehen später
    
    public:
    		point() ;
    		void add_point(double*);
    		void out();
    
    	~point();
    };
    

    Hier die point.cpp:

    #include "point.h"
    
    point::point()
    {
    	points_vec.resize(3);	
    }
    
    void triangle::add_point(double * pointer_create)
    {
    	for (unsigned i = 0; i < 3; i++) {
    		points_vec(i) = *(pointer_create + i);
    	}
    }
    
    void point::out()
    {
    	std::cout << "P1" << points_vec << std::endl;	
    }
    
    point::~point()
    {
    }
    

    So. Mir ist schon klar, dass die Klasse so noch nicht viel Sinn ergibt. Ich werde sie aber erweitern um später damit Dreiecke darzustellen etc. Allerdings habe ich erstmal probeweise die Klasse in "möglichst simpel" erstellt um das Grundkonzept auszuprobieren. Nun habe ich in meiner Main einen std::vector<double> mit einer Reihe von eingelesenen double - Werten (sagen wir mal 300). In dem vector stehen immer die Werte: x1,y1,z1,x2,y2,z2,x3..... usw. (Also immer die drei Koordinaten für mein Objekt der point-Klasse. Nun will ich in einer Schleife dynamisch lauter Instanzen der Klasse point erstellen und diese in ein std::vector<point> schreiben. Das sehe dann ca. so aus:

    #include "point.h"
    #include <vector>
    
    int main(){
    double *pointer_to_start;
    std::vector<double> number_vec;     // Hier drin stehen die 300 eingelesenen Werte.
    std::vector<point> point_vec;
    
    pointer_to_start = &number_vec[0];
    
    for(unsigned int i = 0; i<number_vec.size(); i++){
          point temp_point;
          point_vec.push_back(temp_point);
          point_vec(1).add_point(pointer_to_start+3*i]
    }
    }
    

    Ich bekomme beim Kompilieren allerdings einen Fehler. Und zwar:
    Fehler C4996 'std::_Uninitialized_copy0': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'

    Wenn ich eine Klasse erstelle, und die Koordinaten meiner Punkte als double Werte speichere funktioniert das Kompilieren ohne Fehlermeldung. Die Methode add_point ist bestimmt auch nicht richtig, da ich diese nicht testen kann (weil ich ja einen Fehler bekomme. Aber darum geht es mir in erster Linie gerade garnicht. Ich verstehe nicht warum ich keinen std::<vector> mit Instanzen meiner Klassse erstellen kann.
    Ich entschuldige micht schon einmal im Vorraus dafür, dass meine Frage nicht super präzise gestellt ist. Ich habe mir Mühe gegeben, bin allerdings nocht nicht so fortgeschritten 😕 But: I wish to learn 🙂
    Vielen Dank für eure Hilfe. Sollten noch Angaben fehlen füge ich gerne noch Infos zu.

    Man man man, alles nicht so leicht am Anfang.
    Beste Grüße
    rob...o.0



  • Dass das alles nicht so doll ist, hast du ja schon selber gesagt...
    Zu deinm Fehler (Zeile immer angeben):

    point_vec[1].add... statt point_vec(1).add...



  • Ist das so der Code den du compilierst? Da sind einige Merkwürdigkeiten drin. Z.B. diese Zeile:

    point_vec(1).add_point(pointer_to_start+3*i]
    

    Auf std::vector greift man mit dem operator[] zu, einen operator() gibt es nicht. In der Zeile ist irgendwie alles gemischt und es fehlt auch ein Semikolon am Ende.

    Zu dem Fehler kann ich jetzt so nicht viel sagen wir nichtmal wissen in welcher Zeile der auftritt. Man kann die Warnung zwar deaktivieren (habe ich auch schon gemacht weil Code aus der boost Library diesen ausgelöst hat) aber vielleicht solltest du deine Point Klasse nochmal überdenken. Wenn sowieso immer nur 3 Koordinaten gespeichert werden spricht nichts gegen ein Array oder 3 separate Variablen. Außerdem sollte man solche Funktionen die nur einen Pointer akzetzieren und dann x Elemente lesen.



  • Vervollständigung:
    Außerdem sollte man solche Funktionen die nur einen Pointer akzeptieren und dann x Elemente lesen vermeiden.



  • (zumal er noch nicht mal const ist ;))
    Für dein vorhaben einer punktklasse, welche immer nur 3 Komponenten besitzt, ist ein dynamischer vector Overkill. Ein statisches array oder gleich Variablen x,y,z sollten es auch tun.



  • Guten Morgen!

    Schon mal ein herzliches Dankeschön für eure Antworten - weil jeder meinte die Klasse ergibt keinen Sinn - da gebe ich euch natürlich sofort recht. Aber ich bin eben gerade noch am Verstehen wie das mit dem Programmieren mit C++ so läuft und da ist es für mich einfacher erst einmal die Prinzipien zu testen mit einer sehr simplen Klasse.

    Sorry, das ist nicht der Code den ich so kompiliere. Das war ein Gedächtnisprotokoll um die Fahrtzeit in der Bahn zu nutzen. Das war offensichtlich aber nicht so eine gute Idee - ich werde heute Abend nach der Arbeit nochmal gucken auf welche Zeile sich die Fehlermeldung bezieht und wie mein Code jetzt tatsächlich aussieht.

    Danke für die Hinweise mit dem Pointer. Ich nehme an, das sollte man nicht machen weil man Gefahr läuft, dass der Speicherinhalt an der Stelle überschrieben wird?!
    Habt ihr da einen Vorschlag für mich? Ich habe die Rohdaten, wie gesagt, in einem Vector<Double> alle aufgereiht.

    Und dann noch eine Frage: Wie meintest du das Roflo: sollte ich für die Variable in der Klasse lieber ein Array verwenden? Ich wollte später die Klasse mit einigen Vektoren erweitern und dann die Möglichkeit haben die Vektoren mit mathematischen Funktionen der Boost Bilbliothek zu verwenden. Deswegen habe ich innerhalb der Klasse den Typ <Vector> gewählt.

    Nochmals einen herzlichen Dank an euch!
    Grüße



  • Ich kann mir keine Situation vorstellen, bei der man eine Koordinate mit beliebiger anzahl an komponenten braucht. Entweder ist es ein punkt in der ebene, Raum etc. Dass das während der Laufzeit wechaelt, bezweifle ich.



  • Hallo Roflo,

    Du hast vollkommen recht. Natürlich ändert sich die Anzahl der Koordinaten pro Punkt nicht. Dann mache ich mal ein Array draus. Dann existiert mein Problem auch tatsächlich nicht mehr. Ich habe einfach noch nicht so einen guten Überblick über die Möglichkeiten. Ich Nachhinein betrachtet klingt das nun aber schon logisch.

    Bleibt nur noch die Frage mit dem Pointer. Eigentlich dachte ich das wäre eine clevere Idee, weil die Werte nicht unnötig kopiert werden müssen. So kann man sich irren 🙂

    Grüße!



  • rob...o.0 schrieb:

    Bleibt nur noch die Frage mit dem Pointer. Eigentlich dachte ich das wäre eine clevere Idee, weil die Werte nicht unnötig kopiert werden müssen. So kann man sich irren 🙂

    Prinzipiell stimmt es natürlich, dass weniger kopiert werden muss. Leider ist solcher Code aber sehr anfällig für Programmierfehler und dein Beispielcode ist z.B. auch fehlerhaft weil du 3mal mehr Werte ließt als eigentlich in deinem vector sind. Wenn du schon bei dem Pointer bleiben möchtest wäre wenigstens eine Angabe der Größe beim Aufruf der Funktion add_point sinnvoll. Sonst ist beim Aufruf der Funktion nicht klar, dass diese 3 Werte ließt. Oder alternativ vielleicht sowas:

    void point::add_point(const std::vector<double>& pointer_create)
    {
        points_vec = pointer_create;
    }
    
    for(size_t i = 0; i+2 < number_vec.size(); i += 3) {
        point temp_point;
        temp_point.add_point({number_vec[i], number_vec[i+1], number_vec[i+2]});
        point_vec.push_back(temp_point);
    }
    


  • Und das mit dem Pointer sähe dann so aus (und zumindest ich kriege da nicht die unsage Warnung):

    void point::add_point(const double* pointer_create, size_t n)
    {
        points_vec.assign(pointer_create, pointer_create+n);
    }
    
    for(size_t i = 0; i+2 < number_vec.size(); i += 3) {
        point temp_point;
        temp_point.add_point(&number_vec[i], 3);
        point_vec.push_back(temp_point);
    }
    


  • Super! Vielen Dank für eure Hilfe.

    Beste Grüße



  • Wo kommt eigentlich der Vektor mit den Rohdaten her? Wie liest Du den ein?
    Wahrscheinlich kannst Du auf den auch ganz verzichten...


Anmelden zum Antworten