lista, problem z dodaniem pola na pesel.

0

Witam, mam za zadanie stworzyc listę i jednym z poleceń do niej jest dopisywać osoby do listy.
Wszystko działa, tylko mam problem z dopisaniem pesala do osoby.

class CPerson
{
private:
    string imie;
    string nazwisko;
    int wiek;
    char *pPesel;
 
public:
 
CPerson( string i, string n, int w,   char *pPes);
void CPerson::setPesel(  char *pPes)
{
    strcpy (pPesel , pPes );
 
}
 
char* CPerson::getPesel (void)
{
    return pPesel;
}
...
};
 
 CPerson::CPerson (string i, string n, int w,  char *pPes) : imie(i) , nazwisko(n), wiek(w)
{
    pPesel = new char [12];
    strcpy (pPesel, pPes);
 
}
 
w mainie
 
list <CPerson> lst;
    list <CPerson> ::iterator it;
    it = lst.begin();
 
 
    CPerson wzor1("Jan", "Kowalski", 22, "2323"  );
 
 
    for(int k=0; k<1;k++)
   {
                        cout<<"Dodaj studenta do listy\n";            
 
        char *pesel;
        pesel= new char[15];
                        cout<<"Podaj pesel: \n";
                        cin>>pesel;          
 
            CPerson person6(" ","  ", ' ', "  " );         
 
                        person6.setPesel(pesel);
 
            //cout<<person6.getPesel(); tutaj jak wpisze pesel to sie wyswietla jego zawartosc
 
                        lst.push_back(person6);  // a tutaj juz nie...
 
    }
 
        lst.push_back(wzor1);
 
 
    for ( list<CPerson>::iterator it=lst.begin(); it!=lst.end();it++){
             cout<<*it<<endl;
        }
 

Problem mam w tym, że za pomocą iteratora przy wypisywaniu informacji o nim (imie, nazwisko, wiek, pesel), pesel się nie wypisuje.
Prosiłbym o pomoc, co zrobiłem źle... (konstruktor kopiujacy i operator przypiania stworzylem). Kod się kompiluję i działa, wszystko się wypisuję, tylko nie pesel- dlatego nie zamieszczałem całego kodu... dodatkowo zrobiłem test i jeżeli pole na pesel zadeklaruje jako ( char pPesel[12]) to wtedy działa.. tylko, że mam zrobić jako (char *pPesel) w "celach dydaktycznych".
Z góry dzięki za odpowiedź.

0

skoro korzystasz ze stringów to czemu nie skorzystasz z niego przy peselu?

oh doczytałem że w celach dydaktycznych...
nigdy nie zrozumiem takich celów dydaktycznych.

0
class CPerson
  {
   private:
   string imie;
   string nazwisko;
   int wiek;
   char *pPesel; 
   public:
   CPerson(string i, string n, int w,const char *pPes):imie(i),nazwisko(n),wiek(w),pPesel(strdup(pPes))
   ~CPerson() { free(pPesel); }
   void CPerson::setPesel(const char *pPes)
     {
      free(pPesel);
      pPesel=strdup(pPes);
     } 
   const char *CPerson::getPesel()const 
     {
      return pPesel;
     }
  };

Napisz własną wersje strdup, której wynik będziesz zwalniać za pomocą normalnego delete.

0

zrobiłem taką funkcję ale cały działa tak samo..

char *strdup (const char *p)
{
char *pesel = new char (strlen(p)+1);
memcpy(pesel,p,strlen(p)+1);
return pesel;
}
0
CPerson& CPerson::operator=(CPerson & person)
{
    if (&person == this) return *this;      
                                            
    else
        this->imie=  person.imie;         
        this->nazwisko= person.nazwisko;     
        this->wiek = person.wiek;           
        pPesel = new char [12];
        strcpy(pPesel, person.pPesel);
        
        return *this;
}

CPerson::CPerson(const CPerson &person) 
{
    imie=person.imie;
    nazwisko = person.nazwisko;
    wiek= person.wiek;
    pPesel = new char [12];
    pPesel = person.pPesel;   
}

0

W operatorze przypisania najpierw powinieneś zwolnić pamięć wskazywaną przez pPesel a dopiero potem alokować nową. Tylko ta alokacja jest zupełnie niepotrzebna, bo już masz przydzielony obszar pamięci i tylko zmieniasz jego zawartość.
Komstruktor kopiujący. Od kiedy cstringa można tak skopiować?

0

No faktycznie.. dzięki za odp
owiedź, już poprawilem i dziala. A przy okazji mógłby ktoś wytłumaczyć dlaczego tak trzeba się było męczyć z tym peselem ?

0

To pole wskaźnikowe. Wskazuje na okreśłony obszar pamięci, ale inny w każdym obiekcie. Podczas tworzenia pamięć jest przydzielana a podczas usuwania - zwalniana. Dla takich klas (z polami wskaźnikowymi) należy samemu utworzyć konstruktor kopiujący, operator przypisania, destruktor oraz konstruktor w miejsce tworzonych przez kompilator lub je zablokować (dotyczy konstruktora kopiującego i operatora przypisania).
Same skopiowanie wskaźnika nic nie da (a tak działają wyżej wymienione funkcje w wersji dostarczanej przez kompilator) ,bo będzie on wskazywał na obszar pamięci przydzielony innemy obiektowi i po usunięciu tego obiektu na nie wiadomo co.

0

Ok dzieki, chociaż to wiedziałem- bardziej mnie interesuje dlaczego trzeba było zrobić własną wersję funkcji "strdup" ? Być może z tych samych powodów ? (zrobiłem składnik pesel jako: char pPesel [12] ) i wtedy nie musiałem tej funkcji tworzyć..

0

To czemu nie działało bez tej funkcji? I np. Zamiast free mogę dac delete w programie ?

0
mikhal napisał(a):

To czemu nie działało bez tej funkcji? I np. Zamiast free mogę dac delete w programie ?

Jeżeli alokujesz za pomocą malloc, do zwalniania używasz free. Gdy skorzystasz z new, zwolnić powinieneś pamięć, przy pomocy delete. Zamiennie nie staraj się tego używać.

0

OK. A mógłby ktoś poradzić jak się zabrać za sortowanie tej listy? (np. wg nazwiska), bo natrafiłem się na: http://www.cplusplus.com/reference/list/list/sort/ , tylko u mnie lista nie składa się tylko ze stringów.

0

funkcja:

bool compare_nocase (const CPerson &first,const CPerson &second)
  {
   ...
  }
0

Możesz także zastosować przeładowanie operatora "<" w swojej klasie. Pozwoli to na swobodne porównywanie obiektów według twojego uznania ( np względem wieku ).

W ciele klasy dodaj deklaracje w public:

bool operator < (CPerson a);

Poniżej definicja:

bool CPerson::operator < (CPerson a)
{
	if (a.wiek > this->wiek) 
	return true;
	else
	return false;
}

Oraz przykładowe wywołanie:
sort(object.begin(),object.end());

object.sort()

Wyjaśnienie powyższej zmiany w komentarzach.

Co do zastosowania malloc+free oraz new+delete, nie można ich mieszać nawzajem, powodują one niezdefiniowane zachowanie. W większości przypadków używa się new i delete, gdyż w porównaniu do malloc i free wywołuje on konstruktory i destruktory. Jedyną wadą tego zastosowania jest brak odpowiednika realloc-a.

0

Dzięki za pomoc, zrobiłem sortowanie tylko jakby nie uwzględnia wielkości liter. Mam jeszcze problem z wyszukiwaniem na liście.. mógłby ktoś podpowiedzieć jak to zrobić ? (np. wyszkukiwanie na liście po nazwisku), znalazłem funkcję find_if(), która zwraca iterator do tego znalezionego elementu ale niestety póki co nie wiem jak się za to zabrac.. z góry dzięki za jakieś podpowiedzi.

1 użytkowników online, w tym zalogowanych: 0, gości: 1