TList-Daten nur temporär gespeichert?
-
hi,
ich habe da ein problem, dass sich für mich unverständlich darstellt, da ich keinerlei logik- oder syntaxfehler sehe!!
Ich zeige das konkrete Beispiel:
class index { private: TList* valueList; public: index( TList* i_valueList ); ~index(); void SetValues( TList* i_valueList ); TList* GetValues(); }; //--------------------------------------------------------------------------- void index::SetValues( TList* i_valueList ) { valueList = i_valueList; AnsiString* test = valueList->Items[0]; MessageDlg( *test, mtConfirmation, TMsgDlgButtons() << mbOK, 0); // funktioniert wunderbar, der richtige AnsiString wird ausgegeben } //--------------------------------------------------------------------------- // HIER IST DAS PROBLEM-QUELLSTÜCK: //--------------------------------------------------------------------------- TList* index::GetValues() { AnsiString* test = valueList->Items[0]; MessageDlg( *test, mtConfirmation, TMsgDlgButtons() << mbOK, 0); // funktioniert nicht, statt dem korrekten String wird scheinbar Asicode ausgegeben return valueList; // Rückgabewert der Liste ist deshalb nur aus "Hyroglyphen" bestehend :( } //---------------------------------------------------------------------------
Mittels SetValue übergebe ich ordnungsgemäßg eine gefüllte TList! Dazu habe ich ja immer diesen MessageDlg als Test beigefügt, der eindeutig in der SetValue Funktion noch zeigt, dass die Werte KORREKT sind.
rufe ich die GetValues()-Funktion auf, werden statt der richtigen AnsiString-Werte nur Hyroglyphen/Asci-Codes angezeigt
Woran liegt das, habe ich in der Klassendeklaration etwas falsch gemacht oder warum werden die Werte nicht korrekt in der TList* valueList; gespeichert?
(Im Übrigen wurde natürlich entsprechender Speicher reserviert. Es geht wirklich nur darum, dass in der GetValues()-Fkt. nur noch mist rauskommt, nach der SetValue-Fkt. aber noch alles einwandfrei in der TList* valueList; gespeichert ist. -> siehe MessageDlg-Ausgabewert)
-
egg schrieb:
Im Übrigen wurde natürlich entsprechender Speicher reserviert.
Wo ist der Konstruktor? Wäre bestimmt auch interessant zu sehen.
-
Wie ich das sehe, speicherst Du in der Klasse nur *nen Zeiger auf die uebergebene Liste (bei Set...)!
Wenn Du diese dann irgendwo löschst, bleibt der Zeiger in der Klasse bestehen - zeigt aber ins Nirwana.
Du solltest die Elemente der TList (der uebergebenen) in die TList innerhalb der Klasse uebertragen, nicht den Adresszeiger!
-
thx für eure tipps ich versuchs gleichmal umzusetzen. ich soll also ständig ohne zeiger bei den listen arbeiten?? dann sind die aber leider nicht mehr dynamisch oder versteh ich da was falsch?
Hier erstmal der Konstruktor sowie der Codeausschnitt zur Initialisierung.
index* zeile = new index( i_valueList ); //--------------------------------------------------------------------------- // CLASS: INDEX //--------------------------------------------------------------------------- index::index( TList* i_valueList ) { SetValues( i_valueList ); } //---------------------------------------------------------------------------
-
Hi Altenburger nochmal,
habe versucht, nicht den Zeiger, sondern die Liste an sich der Klassenliste zuzuweisen:
void index::SetValues( TList* i_valueList )
{
valueList = *i_valueList;
}
//---------------------------------------------------------------------------Fehler, ist ja klar: [C++ Fehler] xxx.cpp(157): E2034 Konvertierung von 'TList' nach 'TList *' nicht möglich
Wie mach ich es richtig? Denn in der Klasse ist die TList ja dynamisch (mit Pointer) und bei der Übergabe soll ich ihr jetzt tatsächliche Werte übergeben?
Berücksichtigt dabei bitte auch den gesamten Code den ich gepostet habe. Der beinhaltet jetzt eigentlich alles, was wichtig ist für diese Sache.thx
-
Nee, nee.
Du musst den Inhalt der uebergebenen Liste der Liste Deiner Klasse zuordnen.
1. im Konstruktor mit new ne TList erzeugen (in Klasse)
2. im Destruktor deleten nicht vergessen.3. bei Set...:
alle Items der uebergebenen Liste der Liste der Klasse zuordnen.
Schau Dir mal die Methoden von TList an, speziell Add() u. ä.
Vielleicht gibts auch sowas wie assign() - Hab* gerade kein BCB zur Hand, sorry - da muss ich etwas raten.
-
Ein Assign gibt es bei TList leider nicht.
@egg: Mir ist nicht ganz klar warum du um TList herum da eine Klasse schreiben musst. Wenn es denn unbedingt sein muss, achte bitte darauf, das eine Klasse ihre Daten selbst verwalten sollte (Also, wie Altenburger es vorgeschlagen hat).
Wenn du nur AnsiStrings in die Liste packen willst, schau dir bitte auch mal TStringList an. Die würde hier vieles vereinfachen.
-
Der Code besteht wie obgen, nur mittlerweile an Altenburgers Tipp angepasst:
//--------------------------------------------------------------------------- void index::SetValues( TList* i_valueList ) { for( int i = 0; i < i_valueList->Count; i++ ) { valueList->Add( i_valueList->Items[ i ] ); } AnsiString* test = (AnsiString*)valueList->Items[0]; MessageDlg( *test, mtConfirmation, TMsgDlgButtons() << mbOK, 0); } //--------------------------------------------------------------------------- TList* index::GetValues() { AnsiString* test = (AnsiString*)valueList->Items[0]; MessageDlg( *test, mtConfirmation, TMsgDlgButtons() << mbOK, 0); return valueList; } //---------------------------------------------------------------------------
In der SetValue-Fkt. werden KORREKTE Werte angezeigt, in der GetValue funktion LEERE Werte trotz der tatsächlichen Übertragung auf die Liste, oder hab ich da immer noch was falsch verstanden? Das hoffe ich, denn sonst könnte ich das Problem ja nicht lösen
-
Achja, die Konstruktor und Destruktor-Funktionen habe ich natürlich auch noch aktualisiert:
//--------------------------------------------------------------------------- index::index( TList* i_valueList ) { valueList = new TList; SetValues( i_valueList ); } //--------------------------------------------------------------------------- index::~index() { delete valueList; } //---------------------------------------------------------------------------
-
Hi
Das kann man so jetzt nicht sagen. Da müsstest du uns noch den Code außenherum mal zeigen.
Ich halte es aber prinzipiell für bedenklich Zeiger auf AnsiString zu kopieren. Woher soll deine List denn wissen ob diese Zeiger noch gültig sind?
Besser wäre es die AnsiStrings direkt zu kopieren (ist natürlich aufwendiger).
Ach noch was. Ich halte die Namensgebung deiner Klasse für etwas ungücklich.
Namen wie "index" tauchen alle Nase lang als Variablennamen auf.
Da könnte es leicht zu Verwechslungen kommen.Warum wird denn der Text hier so breit?
-
Moin Braunstein,
danke dass ihr euch immer wieder für meine Problemchen interessiert und helfen wollt.
Besser wäre es die AnsiStrings direkt zu kopieren (ist natürlich aufwendiger).
geht nicht, da die i_valueList, die ich übergebe, aus beliebig vielen Elementen (im Beispiel AnsiStrings) bestehen kann. Das heißt, ich kann die Werte für die valueList nur über eine Hilfsliste übergeben. Man könnte zwar wie du schon sagst mit aufwendigen Umwegen (Funktion mit Index der Liste und AnsiString-Wert) das ganze direkt übergeben, doch finde ich es als gesamte Liste zu übergeben übersichtlicher.
Könnt ihr mir dahingehend nochmal helfen?
Achja:
(1) Wie gesagt, StringList ist nicht gut, da auch ggf. das ganze später noch auf andere Datentypen möglich sein soll.
(2) Der Code, den ich bisher gepostet hat, reicht voll und ganz, da ich die MessageBoxes direkt von SetValues bzw. GetValues aufrufe, und ich euch versichern kann, dass die übergebene i_valueList von beliebig vielen AnsiStrings gefüllt ist und ich die GetValues()-Funktion korrekt aufrufe.vorallem @Altenburger, der mir den Tipp mit der Element-für-Element-Übergeben gab, der leider jedoch wie oben geschrieben nicht funzt
: was mach ich konkret falsch? wie gesagt, muss TList sein, und möchte, dass die AnsiStrings korrekt gespeichert werden, dass eben GetValues() dann entsprechend korrekte Werte liefert.
thx im voraus
-
Was speicherst Du denn in TList (ausserhalb der Klasse!) ???
Die AnsiStrings oder auch nur die Adressen?
Wann löschst Du diese TList (ausserhalb der Klasse!), gleich nach set... oder bei Programmende?Ich denke auch an sowas wie Braunstein sagt:
Du speicherst Adressen von AnsiString. Wenn dann die Originale gelöscht werden zeigen die Zeiger immernoch auf die Stelle im RAM - aber da is nix mehr!
:: Ich würde auch die AnsiString kopieren, nicht die Adressen.
Warum nimmst Du nicht TStringList?
-
@Altenburger
Warum nimmst Du nicht TStringList?
Das habe ich Ihn auch schon mal gefragt, aber bisher noch keine Antwort bekommen.
geht nicht, da die i_valueList, die ich übergebe, aus beliebig vielen Elementen (im Beispiel AnsiStrings) bestehen kann
Was willst du denn damit sagen. Wenn deine index-Klasse auch anderes als AnsiStrings speichern soll, dann würde ich mir mal Gedanken darüber machen woher deine Klasse wissen soll was sie da speichert. Ansonsten gehen ja deine casts daneben. In eine TList AnsiStrings und andere Klassenpointer zu speichern halte ich für eine sehr schlechte Idee.
-
egg,
zeige uns doch BITTE den code außerhalb Deiner Klasse. Insbesondere wie Du die Strings erzeugst, die in der Liste stecken - hierzu ein konstruiertes Beispiel, das zeigt, warum das wichtig ist:
TList* list = new TList; list->Add(new String("Hallo")); //dynamisch erzeugter String ("gehört" nur der Liste) String s = *((String*)(list->Items[0])); //s = "Hallo" { String s2 = "Welt!"; //statischer String ("gehört" dem aktuellen Scope) list->Add(&s2); s = *((String*)(list->Items[1])); //s = "Welt!" } s = *((String*)(list->Items[1])); //statischer String existiert hier nicht mehr ==> s undefiniert