Nytt i forumet
Senaste privatannonserna
Prylar säljes, köpes, bytes och skänkes
| 2012-04-30, 15:34 | #1 |
zolostMedlem Registrerad: feb 2012 |
c++ problem av typen vector.erase()
Hej forumet!
Har ännu ett litet problem med ett program jag håller på att jobba med. Det är ett skolarbete där man gör en varuautomat (säkert fler som har samma program) med valfritt antal produkter mm. Man ska kunna köpa, byta ut, lägga till och ta bort produkter. Nu är jag nästan färdig med allting MEN har stött på problem när man ska ta bort enskilda produkter. En liten sammanfattning av hur programmet ser ut: Jag har gjort en klass som heter Automat. Den består av flera funktioner och variabler men huvudfunktionen är en container av typen list som lägger in nya produkter. Så här ser den ut: list<Automat*> varor; När man startar programmet så anropas automatiskt den här funktionen: void Automat::basutbud() { // för att det från början skall finnas varor i automaten // så börjar programmet med ett anrop av denna funktion som ger automaten 6 varor från start. ant = 0; varor.push_back(new Automat(++ant, "Kexchocklad", 25)); // listans varor allokerar dynamiskt en ny vara med nr, namn och pris på varorna varor.push_back(new Automat(++ant, "Brännvin", 15)); varor.push_back(new Automat(++ant, "Fetaost", 27)); varor.push_back(new Automat(++ant, "Gödsel" , 10)); varor.push_back(new Automat(++ant, "Torkarblad", 15)); varor.push_back(new Automat(++ant, "Trisslott", 30)); } listan varor lägger från start in 6 produkter av typerna int, string och int. alltså nr, namn och pris. so far so good men nu kommer problemet. När man vill ta bort enskilda varor så går det bara att ta bort string-variabeln från listan. Så här ser funktionen ut (lite förenklatt): cout << "Ange numret på varan du vill ta bort....Inväntar val: "; cin >> adminval; // adminval har typen int for(auto it = varor.begin(); it != varor.end(); it++) { if(adminval == (*it)->nr) { (*it)->nr.erase(); // funkar inte...nr har typen int (*it)->namn.erase(); // funkar...namn har typen string (*it)->pris.erase(); // funkar inte...pris har typen int } } när jag försöker köra programmet får jag felmeddelandet: error C2228: left of '.erase' must have class/struct/union för "nr" resp. "pris". en annan funktion jag har som tar bort alla varor funkar felfritt. Den ser ut så här: for(auto it = varor.begin(); it != varor.end(); it++) // loopar igenom varorna delete *it; // tar bort allt allokerat minnesutrymme varor.clear(); // listan består nu av pekare med skräpvärden och även dessa skall tas bort. ant = 0; // nollställ räknaren för antal varor så här är mitt problem helt enkelt. ledsen för att det blev så mycket text men programmet har hunnit bli lite stort nu ![]() hade vart evigt tacksam för hjälp!!! en trevlig valborg till alla!! mvh - johan Senast redigerad av zolost 2012-04-30 klockan 15:40. |
|
|
| 2012-04-30, 17:20 | #2 |
miffoMedlem Plats: Stockholm Registrerad: aug 2002 |
Citat:
Felet du gör är att du försöker köra en vector funtion på delar av en annan struktur. Det du borde göra är: for(iter = vector.begin(); iter != vector.end(); iter++)
{
if ( *iter = dendusökter )
{
vector.erase(iter);
delete *iter;
}
}
__________________
orka |
|
|
| 2012-04-30, 18:39 | #3 |
zolostMedlem Registrerad: feb 2012 |
Hej tack för svar
jag provade att göra som du sa men jag får ett fel av formen: list iterator not dereferencable jag skrev såhär: for(auto it = varor.begin(); it != varor.end(); it++) { if(adminval == (*it)->nr) { varor.erase(it); delete *it; } } kunde inte göra samma jämförelse som i ditt exempel, den ville inte kompilera då |
|
|
| 2012-04-30, 18:59 | #4 |
MagnusLMedlem Plats: Linköping Registrerad: mar 2005 |
std::list/std::vector
std::list<std::shared_ptr<Vara> > varor;
std::cin >> id;
auto it = std::find_if(varor.begin(),
varor.end(),
[id](std::shared_ptr<Vara> vara) {
return (vara->id == id);
});
if (it != varor.end()) {
varor.erase(it);
}
#include <map>
#include <memory>
#include <iostream>
...
std::map<int, std::shared_ptr<Vara> > varor;
varor[0] = std::make_shared<Vara>("Trisslott", 30);
varor[1] = std::make_shared<Vara>("Fetaost", 20);
int id;
std::cin >> id;
auto result = varor.find(id);
if (result != varor.end()) {
varor.erase(result);
}
Senast redigerad av MagnusL 2012-04-30 klockan 19:32.
__________________
Intel Core i7-3770K | AMD RADEON™ HD 7970 3GB | 16 GB DDR3 | DELL U2711 + DELL U2410 |
|
|
| 2012-05-02, 14:55 | #7 |
KaffemaskinenMedlem Registrerad: maj 2012 |
for( auto it = varor.begin(); it != varor.end(); it++ )
{
Automat* ptr = *it;
if( ptr->nr == adminval )
{
varor.erase( it );
delete ptr;
delete *it;
break;
}
}
I ditt föregående inlägg skrev du att det inte kompilerade, vad spottade den ur sig för meddelande? |
|
|
| 2012-05-03, 15:05 | #9 |
perostMedlem Plats: Linköping Registrerad: jun 2007 |
Något att se upp med när du anropar erase på en vector är att alla iteratorer som refererar den vectorn invalideras, eftersom minnet kan allokeras om. Om du fortsätter att iterera med den gamla iteratorn så kommer programmet därför sannolikt krascha. erase returnerar dock en giltig iterator till nästa element i vectorn, så en for-loop som använder erase kan se ut så här:
for(auto it = varor.begin(); it != varor.end(); ++it)
{
it = varor.erase(it);
}
Ditt problem är dock att du verkar ha missförstått vad din vector innehåller. Den innehåller helt enkelt pekare till objekt av typen Automat, så det är Automat-objekten du vill ta bort och inte de ints och strings som Automat innehåller. Du vill alltså bara anropa delete *it för att ta bort ett objekt, och varor.erase(it) för att ta bort pekaren ur vectorn. Men ta dig en funderare på om du verkligen vill lagra pekare i din vector, det är förmodligen bättre att lagra objekten i den direkt istället. Om du verkligen vill lagra pekare så är det bättre att använda shared_ptr som MagnusL visade.
__________________
[Stationär]: i7 930@3.4 | GTX 560 Ti | 12 GB DDR3 1600 | GA-X58A-UD3R | P180B | VX450W | Logitech MX1100 | Realforce 88UB | Arch64 [Bärbar]: HP 5310m | P9400 | 2 GB RAM | Corsair Force F60 | Arch64 |
|
|
Redaktionens senaste nyhetsrubriker
Prylar säljes, köpes, bytes och skänkes