zadanie prezentujace 'konstruktor kopiujący'

Odpowiedz Nowy wątek
2009-11-18 21:46

Rejestracja: 10 lat temu

Ostatnio: 9 lat temu

0

Witam, na zajęcia mam napisać program z wykorzystaniem konstruktora kopiującego. Zadanie polega na tym, że definiujemy stos 4-elementowy i przy próbie umieszczenia na stosie piątego elementu do akcji ma ruszyć konstruktor kopiujący który skopiuje cały obiekt jednocześnie powiększając stos o 4 tak aby możliwe było umieszczenie na nim kolejnych danych.

class klasa
{
   public:  
 int top;
 int *tab;     
 void clear();
 int push(int liczba);
 int pop();
 int size;
 klasa();
 klasa(klasa &kopia);

// ~klasa(){};  //destruktor
      };
/////////////////////////////////////////////////////////////////
void klasa::clear()
{
     size=3;
     top=0;
    std::cout<<"Stos wyczyszczony"<<std::endl;        
            }
 ////////////////////////////////////////////////////////////////////
 int klasa::push(int liczba)
{
    if( top<size)
   {  
        std::cout<<size<<std::endl;
     tab[top]=liczba;
      top++;
     std::cout<<"Element "<<liczba<<" dodany"<<std::endl; 
     } 
    else
    {   
        std::cout<<"Powiekszanie stosu"<<std::endl;  
      tab[top]=liczba;
      top++;
    std::cout<<"Element "<<liczba<<" dodany"<<std::endl; 
    }  
 }  
/////////////////////////////////////////////////////////////////////////
int klasa::pop()
{
    top--;
    std::cout<<"Ostatni element usuniety"<<std::endl;
}
klasa::klasa()
 {
                }
klasa::klasa(klasa &kopia)
{
                  size=size+4;
                   std::cout<<"konstruktor kopiujacy"<<std::endl;
                   }            

Nie za bardzo wiem jak to ma wyglądać. Co ma zawierać konstruktor kopiujący? Prowadzący coś jeszcze wspominał o alokowaniu pamięci dynamicznie.
Mógłby mi ktoś to wytłumaczyć bo męczę się z tym od poniedziałku. Nawet nie wiem czy to co mam jest dobrze.

Pozostało 580 znaków

2009-11-18 22:03
Moderator

Rejestracja: 16 lat temu

Ostatnio: 5 godzin temu

0

Najpierw popraw to co tu wstawiłeś. Bo nie widze tam żadnej alokacji pamięci, a widze odnoszenie się do tablicy...
Ale jeśli chodzi o konstruktor kopiujący to nie widze jego zastosowania w sytuacji którą opisałeś. Konstruktor kopiujący służy do tworzenia NOWEGO obiektu na podstawie starego, a ty przeciez chcesz modyfikować istniejący obiekt...


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...

Pozostało 580 znaków

2009-11-18 22:51

Rejestracja: 10 lat temu

Ostatnio: 9 lat temu

0
  public:  
 int top;
 int tab[4] ;     
 void clear();
 int push(int liczba);
 int pop();
 int size;
 klasa();
 klasa(klasa &kopia);

tak powinno być?

Email od prowadzącego zajecia:

public:
//constructor with no parameters - default size is 4
Stack();
//constructor with one parameter
Stack(int _size);
//copy constructor
Stack(Stack& s);
//destructor
~Stack();

   //adding element to the stack
   void push(int val);
   //getting element from stack
   int pop();
   //clearing stack
   void clear();
   //get stack size

int getStackSize()

   //assignment operator
   Stack& operator=(Stack& s)

private:
int size; //stak size
int top; //position of the top element on stack
int* dane; //data

};

Zapewne widzą Panowie już różnice ale przedstawię poniżej te zagadnienia
które mogą być niejasne.

  1. Pamięć na dane alokujemy dynamicznie z użyciem operatora new. Pamiętamy
    przy tym o zwolnieniu tej pamięci w odpowiednim miejscu klasy.
  2. Domyślny konstruktor – tworzy stos o rozmiarze równym 4.
  3. W momencie gdy próbujemy dodać 5 element do stosu, należy zwiększyć
    rozmiar stosu o 4.
  4. Należy zabezpieczyć przed próbą odczytania pustego stosu.
  5. Proszę zapoznać się z: konstruktorem kopiującym i implementacja
    operatora przypisania. Wiem, że może to być na początku niejasne ale
    musimy szybko się tego nauczyć aby sprawnie przejść do kolejnych ćwiczeń.

Chciał nie chciał, muszę pokazać działający konstruktor kopiujący . W jakiś sposób to musi dać się rozwiązać bo niektórzy zrobili:P Nie da się zrobić tak żeby za każdym razem gdy dochodzimy do końca stosu automatycznie tworzyć nowy stos z powiększoną tablicą, a poprzedni usuwać?

Pozostało 580 znaków

2009-11-18 23:14
Moderator

Rejestracja: 16 lat temu

Ostatnio: 5 godzin temu

0

No i gdzie tam jest niby napisane ze to tego należy użyc owego konstruktora? Zapewniam cię ze nie.
Konstruktor kopiujący i operator przypisania masz po prostu napisac w tej klasie, ale one wcale ci sie nie przydadzą do powiększania stosu.
A zadanie da sie rozwiazać, rzekłbym jest banalne. Ale jak widze ten twój kod powyżej to moja rada: zapomnij i powiedz prowadzącemu ze poprosisz o 1. Nikt tego za ciebie nie napisze, a sam nie umiesz z tego co widać...


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...

Pozostało 580 znaków

2009-11-19 10:53

Rejestracja: 13 lat temu

Ostatnio: 1 rok temu

0

Zapewne widzą Panowie już różnice ale przedstawię poniżej te zagadnienia
które mogą być niejasne.

  1. Pamięć na dane alokujemy dynamicznie z użyciem operatora new. Pamiętamy
    przy tym o zwolnieniu tej pamięci w odpowiednim miejscu klasy.
  2. Domyślny konstruktor – tworzy stos o rozmiarze równym 4.
  3. W momencie gdy próbujemy dodać 5 element do stosu, należy zwiększyć
    rozmiar stosu o 4.
  4. Należy zabezpieczyć przed próbą odczytania pustego stosu.
  5. Proszę zapoznać się z: konstruktorem kopiującym i implementacja
    operatora przypisania. Wiem, że może to być na początku niejasne ale
    musimy szybko się tego nauczyć aby sprawnie przejść do kolejnych ćwiczeń.

Mam dobry humor, więc autorowi wątku przetłumaczę, gdyż najwyraźniej nie zrozumiał treści zadania:

Masz utworzyc klase obiektow, ktora bedzie funkcjonowala jako stos jakichstam elementow. To znaczy, ze przynajmniej musi ona miec dwie publiczne metody: void PUSH(element) = "poloz na stosie" oraz element POP() = "zdejmij ze stosu"
[idea stosu:
Na stos mozna cos wkladac pojedynczo, wtedy nowopołożony element 'przykrywa' te starsze. Ze stosu mozna tez cos zdjac -- ale tylko to ostatniopołozone, bo reszta jest 'przykryta'. Po zdjeciu jednego elementu, ten lezacy o jedno oczko pod nim odkrywa sie i w nastepnym ruchu on zostanie zdjety. Jesli nadal nie rozumiesz, wyobraz sobie zakopana w ziemi cienką rurę do której wrzucasz kolorowe piłeczki. Jak wsadzisz 10 piłek, to za jednym podejsciem dasz rade wyciagnac tylko jedna - te ostatnio wlozona, itp.
]

Twoja klasa ma opierac sie na tablicy dynamicznej.
[
Jako ze w c/c++ "ciezko jest operować różną ilością elementów" oraz "właściwie to mamy tylko zmienne i tablice" -- żeby utworzyć taka klasę obiektów, które mogłyby trzymac X elementów - trzeba uzyc tablicy. To znaczy, ze Twoja klasa powinna zawierac tablice jako jedno ze swoich pol. Jako, ze nie masz zielonego pojecia, ile tych elementow faktycznie moze tam musiec siedziec, tablica ta powinna byc dynamiczna. Skoro ma ona taka byc, to kazdy obiekt klasy powinien sobie taka tablice stworzyc w momencie kiedy uzna za stosowne, zapamietac ja na czas swojej pracy, i potem, kiedys, zniszczyc te tablice, zeby nie zajmowala miejsca w pamieci.
]

dodac piaty element - powieksz o 4.
[
Operacje 'powiekszania' tablicy dynamicznej sa upierdliwe. Mowiac w skrocie, NIE DA sie jej powiekszyc. Trzeba stworzyc nowa (wieksza), przepisac stare elementy do nowej, wywalic stara tablice, i od tej pory uzywac juz tylko nowej. Nie dosc ze upierdliwe, to jeszcze czasochlonne. Wyobraz sobie, ze masz tablice o 100000 elementow i chcesz do niej dopisac jeden wiecej. No to ten 100000 elementow musisz przepisac. O, a teraz musisz dodac jeszcze jeden. Znowu przepisujesz 100001 elementow. Zżera czas! Zeby nie tracic czasu, przy kazdym powiekszeniu tablicy, mozna sobie ja powiekszyć "na zaś". Dopisujac element, zamiast z 100000 -> 100001, zwieksz ja z 100000 -> 110000 i dopisz element na pozycji 100001. Za nastepnym dopisaniem elementu, nie musisz powiekszac, tylko od razu wpisujesz na 100002 ! Zeby to osiagnac, musisz pamietac nie tylko ROZMIAR tablicy, ale takze ILOSC ELEMENTOW. Po powiekszeniu na zas, masz w tablicy 100001 elementow, ale tablica ma 110000 przegródek. Bez ekstra pamietania liczby elementow, skad bedziesz wiedziec, gdzie dopisac kolejny?
]

Domyslny konstruktor ma startowac z wielkoscia dyntablicy = 4
[
Podpowiedz w zywe oczy, tablica dyn. ma byc tworzona w konstruktorze. To znaczy, ze ma byc pewnie usuwana w destruktorze. Wymaganie jest w miare jasne - jak tworzysz ja, to ma miec rozmiar 4 elementow. Ma to silny zwiazek z uwaga o jedno oczko powyzej. Jaki ma sens domyslne tworzenie stosu o 4 elementach? Jakie te elementy mialyby miec wartosci? Bezsensu. Dyntablica ma startowac z wielkoscia 4, ale STOS ma startowac jako PUSTY! Chodzi o to, ze stos ma na starcie "na zaś" jedynie przygotować sobie 4ry puste przegródki na elementy..
]

Uwaga na pusty stos.
[
Jezeli ilosc elementow na stosie spadnie Ci do ZERA, w jaki sposob ma zadzialac metoda POP ? skoro na stosie jest kompletnie pusto, jak ona sobie wyczaruje wartosc? Musisz przed tym jakos się ochronic - np. zglosic wyjatek, albo zwrocic jakis kod bledu.
]

Dodac prawidlowy cctor, czyli copy constructor.
[
Domyslny ctor ma tworzyc pusty stos z 4 przegródkami. Uzywany on jest jak tworzysz sobie np. nowa zmienna typu 'stos'. Kopiujacy jest zas uzywany w momencie, gdy tworzysz jakas zmienna typu stos, ale na podstawie innej zmiennej. np:
int x = 5; // sens linijki jasny? powiedzmy ze tutaj bylby uzyty ctor
int y = x; // sens linijki jasny? powiedzmy ze tutaj bylby uzyty copyctor
Stos mojstos; // ctor!
Stos mojdrugistos(stos); // copy ctor!
Stos mojdrugistos = stos; // copy-ctor! ale: tylko dlatego ze specjalny przypadek podstawienia.
Mam nadzieje ze jasne. CopyCtor ma wiec obiekt skopiowac, tak zeby mozna bylo miec od teraz dwie zmienne o takiej samej 'zawartosci'. To znaczy, ze copyctor musi oberzec ten-drugi-oryginalny obiekt bardzo dokladnie, a nastepnie moj-wlasnie-tworzony obiekt poustawiac tak, aby byl identyczny z oryginalem, ale NIE TAKI SAM. To znaczy, ze mozesz skopiowac sobie ilosc elementow i rozmiar tablicy, ale juz nie mozesz sobie skopiowac wskaznika na dyntablice! Jesli bys to zrobil, oba obiekty, stary i nowy, uzywaly by TEJ SAMEJ tablicy, i nawzajem mieszalyby sobie w elementach. Trzeba skopiowac tablice, a nie tylko wskaznik
]

I ostatnia rzecz: skoro kazano Ci spelnic takie a nie inne wymagania, Twoj program, w main, poza stworzeniem sobie jednego albo kilku stosow, powinien takze zawierac ekstra takie operacje na tymze(tychze) stos(ach), aby bylo ladnie widac, ze:

operacje push-pop dzialaja tak jak nalezy</li> ze stos naprawde powieksza swoja wewnetrza dyntablice w skokach co 4 oczka, a nie co chwila co jedno oczko</li> konstruktor kopiujacy faktycznie dziala</li> konstruktor kopiujacy tworzy dwa niezalezne obiekty. pushpop na jednym nie zmienia tego drugiego</li> program nie wywali sie gdy stos zejdzie do zera elementow, i pokaze reakcje stosu, jak ow sprobuje zejsc ponizej

Z tym, powinienes dostac maksymalna liczbe pktow.</li> </ul>

A teraz, IMHO, mam prawo wyrazić uwagę, więc też ją przeczytaj:

Prowadzący potraktował skrótowo opis zadania, i jeśli poziom waszego rocznika jest sam z siebie cienki, miałeś prawo nie wiedzieć o co chodzi.
Jednakże, jeżeli po powyższym wyjaśnieniu, dalej nie jesteś w stanie SAM napisać tego zadania w ciagu kilku dni, to serio, uwaga Shalom'a o ocenie zacznie nabierać sensu.

ganbatte


ps. nie oczekuj nastepnym razem podobnych wyjasnien..


no to pojechałem z nieobecnością.. chwila przerwy i prawie rok przeleciał

Pozostało 580 znaków

Odpowiedz

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