Klassenentwurf
-
akari schrieb:
Hallo
Burkhi schrieb:
..noch ergänzend dazu:
In structs sind alle Members standardmässig public, in classes private.Das habe ich in meinem Post auf Seite 1 schon geschrieben, das von dir zitierte ist nur die Wiederholung.
bis bald
akariOh Pardon, hab ich glatt übersehen
-
ok danke für den Tipp.
Die Kompilierung läuft durch. Nachdem ich meine Dateien ausgewählt habe und den Datensatz anlege bricht das Programm mit einer EAccessViolation ab. Wenn ich den Haltepunkt in die ImportData-Methode setze kommt der Programmabbruch in der Zeile "VData[i][j].value = temp_value;"void CDataset::ImportData(TStringList* stlPaths_) { for (int i=0; i<stlPaths_->Count; i++) { //hier war noch ein Fehler, da stand vorher stlPaths_->Capicity std::auto_ptr<TStringList> stlData(new TStringList); stlData->LoadFromFile(stlPaths_->Strings[i]); for (int j=0; i<stlData->Count; i++) { TDateTime temp_timestamp; double temp_value; SplitString(stlData->Strings[j], &temp_timestamp, &temp_value); VData[i][j].value = temp_value; //hier bricht das Programm ab! VData[i][j].timestamp = temp_timestamp; VData.push_back(std::vector<SValue>()); // erste Ebene füllen VData[j].push_back(SValue()); // zweite Ebene füllen } } }
-
Hallo
Ich habe nicht den Eindruck, das du überhaupt verstehst, was du programmierst...
Denn sonst würde dir auffallen, das du zuerst Daten in den vector schiebst, und erst danach den Platz im vector schaffst, wo die Daten eigentlich hinsollen.bis bald
akari
-
Ich stimme akari voll zu und würde dir (rudpower) raten dich mal über vector etwas gründlicher schlau zu machen.
In guter Einstieg dafür bietet das hiesige Magazin. Z. Bsp. hier
http://www.c-plusplus.net/forum/143816
In diesen Fall hier könnte man auf push_back sogar ganz verzichten und std::vector::resize bemühen. Immerhin steht die Größe des vectors ja schon vorher fest.
-
so, nun hab ich mich nochmal genau mit vector beschäftigt. War klar, dass das nicht funktioniert wenn ich auf Elemente zugreife, die noch nicht reserviert wurden. Hier nun der funktionierende Code:
void CDataset::ImportData(TStringList* stlPaths_) { VData.resize(stlPaths_->Count); for (int i=0; i<stlPaths_->Count; i++) { //durchläuft alle Dateien in der Stringliste std::auto_ptr<TStringList> stlData(new TStringList); stlData->LoadFromFile(stlPaths_->Strings[i]); for (int j=0; j<stlData->Count; j++) { TDateTime temp_timestamp; double temp_value; SplitString(stlData->Strings[j], &temp_timestamp, &temp_value); VData[i].resize(stlData->Count); VData[i][j].value = temp_value; VData[i][j].timestamp = temp_timestamp; } } }
Vielen Dank nochmal für die Hilfestellungen und ein schönes Wochenende.
-
Da ist noch ein Fehler drin.
Das zweite resize muss eine Schleife nach oben verschoben werden sonst machst du es viel zu oft.
-
Burkhi schrieb:
akari schrieb:
Hallo
Burkhi schrieb:
..noch ergänzend dazu:
In structs sind alle Members standardmässig public, in classes private.Das habe ich in meinem Post auf Seite 1 schon geschrieben, das von dir zitierte ist nur die Wiederholung.
bis bald
akariOh Pardon, hab ich glatt übersehen
Sorry für den Spam, aber ich bitte Burkhi mich über Private Nachricht anzuschreiben, ist wichtig. Oder geht das in diesem Forum nicht?
-
Hallo
Reptilex schrieb:
Sorry für den Spam, aber ich bitte Burkhi mich über Private Nachricht anzuschreiben, ist wichtig. Oder geht das in diesem Forum nicht?
Die privaten Nachrichten sind in diesem Forum deaktiviert.
Burkhi hat in seinem Profil auch keine E-Mail Adresse hinterlegt. Also kannst du Burkhi bitten, das er dir eine E-Mail schickt, an die Adresse in deinem Profil.bis bald
akari
-
akari schrieb:
Hallo
Reptilex schrieb:
Sorry für den Spam, aber ich bitte Burkhi mich über Private Nachricht anzuschreiben, ist wichtig. Oder geht das in diesem Forum nicht?
Die privaten Nachrichten sind in diesem Forum deaktiviert.
Burkhi hat in seinem Profil auch keine E-Mail Adresse hinterlegt. Also kannst du Burkhi bitten, das er dir eine E-Mail schickt, an die Adresse in deinem Profil.bis bald
akariHallo,
okay dann mach ich das hiermit:
Burkhi, bitte schreibe mir eine Mail an meine E-Mail damit ich dir dort schreiben kann!
Schade, dass man ihn nicht leichter kontaktieren kann
-
Soweit funktioniert es: Leider gibt es beim Schließen des Programms eine Exception:
Im Project1.exe ist eine Exception der Klasse EAccessViolation augetreten. Meldung: 'Zugriffsverletzung bei Adresse 004026DE im Modul 'Project1.exe'. Lesen von Adresse 00000064'. Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
Ich vermute, dass irgendwo Speicherlecks entstehen beim Schließen der Anwendung.
Nach dem Schließen der Anwendung bleibt er im Code an der Stelle for (int i=0; i<count; i++) stehen. Hier scheint irgendwo ein Fehler zu sein.void __fastcall TfrmMain::lviewDatasetSelectItem(TObject *Sender, TListItem *Item, bool Selected) { int index = Item->Checked; //welcher Datensatz ausgewählt int count = VDataset[index].GetVFilenames().size(); for (int i=0; i<count; i++) { lboxData->Items->Add(VDataset[index].GetVFilenames()[i]); TLineSeries *serImportedData = new TLineSeries(Chart1); serImportedData->ParentChart = Chart1; for (unsigned int j=0; j<VDataset[index].VData[i].size(); j++){} serImportedData->AddXY(VDataset[index].VData[i][j].timestamp, VDataset[index].VData[i][j].value, "", clBlue); serImportedData->AddY(VDataset[index].VData[i][j].value, "", clBlue); } }
Vielleicht liegt der Fehler auch beim Anlegen des Datensatzes. Der Vektor Datensatz ist ja in private der frmMain (das ist bei mir die erste Form) deklariert. Dazu gibt es eine Schnittstelle:
std::vector<CDataset> &TfrmMain::GetVDataset() { return VDataset; }
In einer zweiten Form wird der Datensatz über einen Button angelegt:
void __fastcall TfrmNewDataset::btnCreateNewDatasetClick(TObject *Sender) { std::auto_ptr<TStringList> stlPaths(new TStringList); //alle markierten Dateien in Stringliste schreiben: for (int i=0; i<lviewData->Items->Count; i++) { TListItem* item = lviewData->Items->Item[i]; if (item->Checked) stlPaths->Add(lviewData->Items->Item[i]->Caption + lviewData->Items->Item[i]->SubItems->Strings[0]); } //neuen Datensatz anlegen und Messdaten importieren: frmMain->GetVDataset().push_back(CDataset()); frmMain->GetVDataset().back().ImportData(stlPaths.get()); frmMain->GetVDataset().back().SetPlantOperator(cmbLocation->Text); frmMain->GetVDataset().back().SetIdentifier(txtIdentifier->Text); Close(); }
Vielleicht ist es besser den Vektor in der zweiten Form zu deklarieren und dort eine Schnittstellenmethode zu schreiben?