Frage zu ArrayList



  • Hallo,

    und wiedermal muss ich fragen :
    Ist das so richtig ?
    Ich möchte später mal eine Anwendung schreiben in der mehrere Wegpunkte ( aus der fliegerei ) mit Latitude und Longitude gespeichert und abgerufen werden müssen.
    Nun binich in meinem Büchlein auf die ArrayList gestoßen und hab mal ein bischen probiert :

    // die TestKlasse
    ref class CTester
    {
    private:
    	Double m_lat, m_lon;
    	String^ m_name;
    public:
    	CTester(Double Lat, Double Lon, String^ Name)
    		:m_lat(Lat), m_lon(Lon), m_name(Name)
    	{}
    
    	virtual String^ ToString() override	{
    		return(m_name+" "+m_lat+" "+m_lon);
    	}
    };
    
    int main(array<System::String ^> ^args)
    {
    	ArrayList^ myAL = gcnew ArrayList;
    
    	myAL->Add(gcnew CTester(12.11, 34.11, "Wegpunkt 0"));
    	myAL->Add(gcnew CTester(13.12, 34.22, "Wegpunkt 1"));
    	myAL->Add(gcnew CTester(13.13, 34.33, "Wegpunkt 2"));
    	myAL->Add(gcnew CTester(13.14, 34.44, "Wegpunkt 3"));
    
    	for(int x=0; x<myAL->Count; x++)
    		Console::WriteLine(myAL[x]);
    
        Console::ReadKey();
        return 0;
    }
    

    Das ganze erfüllt noch keinen wirklichen sinn, ist also nur mal so zum testen, aber die Frage ist ja auch nur ob man das so macht und ob das so richtig ist ?
    Ich meine speziell das gcnew CTester() bei jedem hinzufügen.

    Matthias



  • Verwende als "Collection" liebe eine Typsichere Klasse. Da sparst Du Dir eine Menge Ärger:

    ref class TesterList : public System::Collections::Generic::List<CTester^>
    {
    };
    
    Und dann natürlich:
    int main(array<System::String ^> ^args)
    {
        TesterList^ myAL = gcnew TesterList();
    
        myAL->Add(gcnew CTester(12.11, 34.11, "Wegpunkt 0"));
        myAL->Add(gcnew CTester(13.12, 34.22, "Wegpunkt 1"));
        myAL->Add(gcnew CTester(13.13, 34.33, "Wegpunkt 2"));
        myAL->Add(gcnew CTester(13.14, 34.44, "Wegpunkt 3"));
    
        for(int x=0; x<myAL->Count; x++)
            Console::WriteLine(myAL[x]);
    
        Console::ReadKey();
        return 0;
    }
    

    PS: Und lass das "C" vor Deinen Klassen-Namen weg!!! Was soll denn das sein!? Das wird normalerweise nur bei MFC-Klassen verwendet!



  • Hallo,

    also war ich diesmal auf dem richtigen weg bis auf die Typsicher Klasse und das C vor dem Klassennamen. Ok, das kann ich ja weglassen.
    Werd mir mal anschauen was ganz GENAU Typsicher bedeutet, denn das hab ich bisher noch nicht gehört/gewusst.
    Wenn Du Lust hast kannst Du ja nochmal schreiben , ansonssten ist eigentlich dann alles klar.

    Was für Ärger ?
    Typsicher ?

    Danke Dir !
    Matthias



  • STF-DIR schrieb:

    Was für Ärger ?
    Typsicher ?

    Mit einer ArrayList geht folgendes nicht:

    CTester ^a1 = al[1];
    

    Mit der TesterList-Klasse dageben schon! Das bedeutet in diesem Fall "Typsicher" (d.h. der *Compiler* ist sich zur Compilezeit sicher, dass der *korrekte* Typ in der Liste drin ist. In einer ArrayList kann hingegeben *jeder* Typ drin sein!



  • Die Typsicherheit müsste sich doch aber auch mit einem reinen

    System::Collections::Generic::List<CTester^>
    

    und ggf TesterList als typedef darauf herstellen lassen ohne eine leere Klasse erben zu lassen.



  • Knuddlbaer schrieb:

    Die Typsicherheit müsste sich doch aber auch mit einem reinen

    System::Collections::Generic::List<CTester^>
    

    und ggf TesterList als typedef darauf herstellen lassen ohne eine leere Klasse erben zu lassen.

    Prinzipiell schon, aber so ein konstrukt hat Nachteile, wenn Du dieses an mehreren Stellen verwenden willst.
    Du musst dann immer diesen Langen Namen schreiben und kannst z.B. später keine eigenen Methoden (z.B. zum auffinden von bestimmten ELementen) aufnehmen.
    Deshalb bevorzuge ich immer eine (leere) Ableitung, welche einen simplenNamen hat und eine zentrale Stelle zur Ergänzung von eigenen Methoden vorhanden ist.

    Also ich Rate zu einer Ableitung.



  • Du musst dann immer diesen Langen Namen schreiben

    Naja, dafür lässt sich typedef verwenden, der später auch durch eine Vererbund ersetzt werden kann.

    Der Nachteil der Vererbung wäre IMHO, das man viel zu schnell Methoden implementiert weil es einfach und bequem ist (die Klasse existiert ja schon).

    Auf dem Typedef eine Klasse zu machen ist nachträglich wenig aufwand, für eine Änderung der leeren Klasse muss ich auch alle Units die damit zu tun haben neu übersetzen.

    Einfach zwei verschiedene Ansichten....



  • ja ok... "typedef" ist eine Alternative:

    typedef System::Collections::Generic::List<int> MyTList;
    

    Schon wieder ein Vorteil von C++/CLI gegenüber C#!



  • Hallo,

    leider spinnt mein VC 2005 derzeit .. wenn das wieder geht werd ich das probieren.

    Aber 1. Frage an Jochen:

    typedef System::Collections::Generic::List<int> MyTList;

    soll doch sicher

    typedef System::Collections::Generic::List<CTester^> MyTList;

    heißen oder liege ich da falsch ?

    2. Frage:

    Es sind ca. 71.000 !! Zeilen in der Datei mit den Wegpunkten.

    SPA,Z98 ,001,BADJA,-32.033056, 117.522222, 0, 75,B,B
    SPA,Z98 ,002,DULYA,-31.661111, 119.069167, 254, 74,B,B
    SPA,Z98 ,003,NALAR,-31.309444, 120.455278, 253, 59,B,B
    SPA,Z98 ,004,KG,-30.789722, 121.452778, 238, 0, ,B
    MES,Z994 ,001,BUNDU, 25.006667, 52.490000, 0, 121,B,B
    MES,Z994 ,002,VEBAT, 24.808333, 52.850000, 301, 106,B,B
    MES,Z994 ,003,DASLA, 24.629722, 53.546667, 286, 106,B,B
    MES,Z994 ,004,MISOD, 24.316667, 54.733333, 286, 127,B,B
    MES,Z994 ,005,NOBTO, 23.923611, 55.311111, 307, 0, ,B

    Sieht so aus.
    Wie würdet Ihr sowas verwalten ?
    Ich möchte die Datei schon erst mal in eine Datendatei umwandeln denke ich und dann als *.dat in dem Programm laden.
    Also ein extra Programm um diese TextDatei in eine *.dat umzuwandeln und die *.dat dann im Programm verwenden oder ?
    ( die daten ändern sich ja auch Monatlich )

    Matthias



  • typedef System::Collections::Generic::List<int> MyTList;

    soll doch sicher

    typedef System::Collections::Generic::List<CTester^> MyTList;

    heißen oder liege ich da falsch ?

    Genau genommen mein Jochen:

    typedef System::Collections::Generic::List<T> MyTList;
    

    Nicht jedes Beispiel ist exakt auf Deine Anforderungen zugeschnitten. (Falls noch nicht bekannt: Einem Template werden Typen übergeben, welche sind grob gesehen egal für das Template, es erfüllt mit int, CTester oder mit T genau den gleichen Zweck).

    Wo wäre denn der Unterschied von der Textdatei zur dat Datei ? Eventuell wäre es Sinvoller die Daten in eine Datenbank zu packen. Damit lassen sich leichter Auswertungen machen und Du kannst ADO.Net anwenden.

    Für den Import bietet sich dann ggf. eine extra Applikation an, die die Daten parst und in die Datenbank einfügt.



  • Hallo,

    also ist

    System::Collections::Generic::List
    

    ein Template wenn ich das jetzt richtig verstanden habe oder ?
    Templates sind bekannt.

    Nicht jedes Beispiel ist exakt auf Deine Anforderungen zugeschnitten.

    Das bringt mich manchmal ganz schön durcheinander. Ich kann manchmal ( noch hoffe ich ) nicht die richtigen Rückschlüsse aus Euren Beispielen ziehen.
    Das muss ich wohl noch lernen.

    ADO.NET ist ( da bin ich mir sicher ) ein guter Vorschlag, aber ich glaube da bin ich absolut noch nicht so weit 🙂

    Ich dachte mir eigentlich erst mal die TextDatei mit den Wegpunktdaten in eine Datendatei umzuwandeln damit nicht jeder drin herumwurschteln kann.
    Danach die Datei im Programm laden, aber als was ?
    Was ist da günstig, ein Array, ein Vector .. was nimmt man da am besten ?

    Sind nicht eigentlich auch einfache Strukturen prädistiniert dafür einfache Daten aufzunehmen ?
    An den Daten wird ja im Programm selber nichts verändert.

    Hmmm

    Matthias



  • STF-DIR schrieb:

    ein Template wenn ich das jetzt richtig verstanden habe oder ?

    Nein, ein Generic. Der Unterschied zum Template ist (im Wesentlichen), dass Generics bei ihrer Definition bereits in Bytecode übersetzt werden, Templates aber erst bei ihrer Benutzung (Instanzierung). Ausserdem sind Templates in einigen Belangen flexibler, aber wartungsunfreundlicher.



  • Hallo,

    ok, das Kapitel mit Collections kommt als nächste in meinem Büchlein, dann werd cih mal weiterlesen.

    Dank Euch allen !

    Matthias



  • Ich dachte mir eigentlich erst mal die TextDatei mit den Wegpunktdaten in eine >Datendatei umzuwandeln damit nicht jeder drin herumwurschteln kann.

    Hm, da ist der Mehraufwand zu hoch. Nimm die Datei wie sie kommt. IMHO machst es Dir mit der .dat einfach schwerer. (Einfach umbenennen ist wohl nicht gemeint und umbasteln der Daten macht es Dir unnötig schwer)

    Templates aber erst bei ihrer Benutzung (Instanzierung).

    Templates werden eigentlich beim Compilieren aufgelöst. Bei der Instanziierung existiert IMHO kein Template mehr.



  • Knuddlbaer schrieb:

    Templates werden eigentlich beim Compilieren aufgelöst. Bei der Instanziierung existiert IMHO kein Template mehr.

    Vollkommen richtig. Ich hätte wohl sagen sollen "Bei Templates werden erst konkrete Instanzen in Bytecode übersetzt" 😉



  • Jup, schon klar, wollte es für den Threadersteller erwähnt haben bevors wieder chaos gibt 😃 🤡



  • Hallo,

    ok Ihr sagt also die txt Datei so lassen.
    Mit so einer einzelnen Zeile einlesen ist es aber später mam nicht getan.
    Hier mal der Ablauf : ( wp = wegpunkt , kein cpp code)

    SPA,Z98 ,001,BADJA,-32.033056, 117.522222, 0, 75,B,B

    1. Aufsplitten
    wp->Land = spa,
    wp->Airway = Z98,
    wp->Nr = 001,
    wp->Name = Badja,
    wp->Lat = -32.033056,
    wp->lon = 117.522222,
    wp->hdgfrom = 0, // Kurs from
    wp->hdgto = 75, // Kurs to
    wp->awhight = b // Luftstraßeneinteilung

    wp->Typ = ??? // Wird aus einer anderen Datei geholt

    So, das als erstes mal und dann geht es aber noch weiter.
    Das blöde an den Wegpunkten ist aber das es Bamki z.B. einmal hier in Leipzig gibtg und nochmal irgendwo anders.
    Der Unterschied zwischen beiden ist natürlich lat und lon.
    Später soll das Programm ja mal einen Flugplan erstellen.
    Das heißt ich brauche für den A* Algorythmus eine Start und Zielnode.
    Weil es aber die Wegpunktnamen mehrmals gibt muss das Zusammengesetzt werden.
    Also Bamki_12.2233_51.2323 z.B. Das funktioniert nur so, hab ich ja schon so gemacht und funktionierte perfekt.

    Dann müssen ja noch Entfernungen Berechnet werden usw. Da muss also noch so einiges gemacht werden mit den Daten.
    - Ständig nach Wegpunkten in einem bestimmten Radius suchen
    - Daten als OpenGL darstellen
    usw.

    Deswegen dachte ich eine Datendatei wäre schneller eingelesen.
    Damals in ( sorry dafür und bitte keine Diskusionen darüber ) "Delphi" hab ich einen Record gemacht und in dem extra Programm die TestDatei als Record abgespeichert. Diese *.dat Datei konnte man dann in "einem Rutsch" komplett einlesen.
    Das ging rasend schnell.
    Das war der Grund für die Frage.

    Muss ich also , nach euren Aussagen, diesen Umweg gar nicht mehr gehen ?

    Wäre ja ein riesen Vorteil von C++ !!

    Matthias



  • Naja, durch vorenthalten von Informationen wirst Du nicht auf das Ergebniss kommen was Du haben willst.

    Mit reinem Argument, der Anwender soll in den Daten nicht einfach per Texteditor was ändern sollen ist ein völlig anderer Standpunkt wie: Der Parser wird aufwendig.

    Letzendlich bleibt es Dir überlassen was Du machen willst, nur Du kennst die genaue Anforderung und musst die Vor und Nachteile abwegen.

    Generell musst Du aber so oder so eine Routine schreiben, die die Textzeilen auswertet, denn in die .dat Datei muss es ja erst einmal gebracht werden.

    Denke Dir also den Parser durch und prüfe dabei, ob der Gewinn das konvertiert einzulesen den Aufwand der Konvertierung lohnt.

    Kurz:
    Du kommst ums Zeilen lesen so oder so nicht herum (annahme: Du kannst das Rohformat der Daten nicht beeinflussen die Du geliefert bekommst).

    Das vorgehen ist unabhängig der Programmiersprache, die Implemeniterung und Details unterscheiden sich lediglich.



  • Hallo,

    das Rohdatenformat kan ich nicht ändern.
    Ja, um das Zeilenweise einlesen komm ich sowieso nicht herum

    Ich werd das genau so machen und testen was besser ist, alles in einem Programm mit den Rohdaten so wie sie sind oder extra ein kleines Programm welches die Daten nur ins Binäre umwandelt.

    Das bring außerdem noch den gewünschten Lerneffekt 🙂

    Danke Euch
    Matthias


Anmelden zum Antworten