Problem z przypisaniem wektora wektorowi

0

Witam,
mam takie pytanie. Tzn. może inaczej wstawiam listing:

#include <iostream>
#include <conio.h>
class wektor
{ private:
	int roz;
	int *tab;
public:
	wektor();
	~wektor();
	void zmien_element(int x, int poz);
	void zmien_rozmiar(int x);
	wektor(int x);
	int zwroc_element(int poz);
	int zwroc_rozmiar();
wektor operator=(wektor p);


};

wektor wektor::operator=(wektor p)
{
       printf("\n========================= Operator= =========================");
       if(tab) {delete tab;}
       roz=p.roz; tab=new int[roz];
       for(int i=0;i<roz;i++) tab=p.tab;
       printf("\n\n ptab[0]= %d",p.tab[0]);
       printf("\n========================= Operator= KONIEC =========================");
       getch();
       return *this;
}


wektor::wektor()
{
       roz=5;
       tab=new int[roz];
       for (int i=0; i<5; i++) tab[i]=0;
}

wektor::~wektor()
{
       if (tab!=NULL)
       {delete tab; tab=NULL; roz=0;}
}

void wektor::zmien_element(int x, int poz)
{
       printf("\n========================= Zmien element =========================");
       printf("\n zmiana elementu tab[%d]=%d ->",poz,tab[poz]);
       if (poz<roz && poz>=0)
       tab[poz]=x;
       printf(" tab[%d]=%d",poz,tab[poz]);
       printf("\n========================= Zmien element KONIEC =========================");
       getch();
}

void wektor::zmien_rozmiar(int x)
{ 
       if(tab!=NULL) {delete tab;}
       if (x>10) x=10; if (x<1) x=1;
       roz=x;
       tab=new int[x];
}

wektor::wektor(int x)
{
       roz=x;
       tab=new int[roz];
       for (int i=0; i<x; i++) tab[i]=0;
}

int wektor::zwroc_element(int poz)
{
       if (poz<roz && poz>=0)
       {
        	return tab[poz];
       }
}

int wektor::zwroc_rozmiar()
{ 
       return roz;
}


int main()
{
    using std::cout;
    wektor p,z,x,y;
    printf("\n rozmiar p %d z %d x %d y %d", p.zwroc_rozmiar(), z.zwroc_rozmiar(), x.zwroc_rozmiar(), y.zwroc_rozmiar());
    for (int i=0; i<p.zwroc_rozmiar();i++) printf("\n p[%d] %d",i,p.zwroc_element(i));
    for (int i=0; i<z.zwroc_rozmiar();i++) printf("\n z[%d] %d",i,z.zwroc_element(i));
    for (int i=0; i<x.zwroc_rozmiar();i++) printf("\n x[%d] %d",i,x.zwroc_element(i));
    for (int i=0; i<y.zwroc_rozmiar();i++) printf("\n y[%d] %d",i,y.zwroc_element(i));
    getch();        
    for (int i=0; i<p.zwroc_rozmiar();i++) 
    {
         p.zmien_element(i+1,i);
         printf("\n p[%d] %d",i,p.zwroc_element(i));
    }
    printf("\n Po zmianie");
    printf("\n Zmiana elementow z");
    getch();
    for (int i=0; i<z.zwroc_rozmiar();i++) 
    {
         z.zmien_element(i+2,i);
         printf("\n z[%d] %d",z.zwroc_element(i));
    }
    printf("\n Po zmianie");
    for (int i=0; i<p.zwroc_rozmiar();i++) printf("\n p[%d] %d z[%d] %d",i,p.zwroc_element(i),i,z.zwroc_element(i));
    getch();
    printf("\n Proba przypisania wektorowi x wektora p");
    printf("\n Wektro x przed: ");
    for (int i=0; i<x.zwroc_rozmiar();i++) printf("\n x[%d] %d p[%d] %d",i,x.zwroc_element(i),i,p.zwroc_element(i));
    x=p;
    for (int i=0; i<x.zwroc_rozmiar();i++) printf("\n x[%d] %d p[%d] %d",i,x.zwroc_element(i),i,p.zwroc_element(i));
    getch();

     return 0;
}

Sprawa tyczy się tego:

x=p;

Dlaczego jeszcze w "wektor wektor::operator=(wektor p)" x[0]=1 oraz co ważniejsze p[0]=1, a po wyjściu jest już jakaś masakryczna liczba w x[0] oraz p[0]?
Zabiło mi to ćwieka, siedzę nad tym dwa dni i nic :/
Prosiłbym bardzo o pomoc w rozwiązaniu tego dokuczliwego problemu ;)
Z góry dziękuję.

0

Musisz zrobic konstruktor kopiujacy (ew nie kopiowac niczego - czyli nie przekazywac/zwracac po wartosci).

0

Dzięki za szybką odpowiedź. A teraz dalej:

wektor::wektor(const wektor & rhs)
{
       *roz=rhs.zwroc_rozmiar();
       tab=new int[roz];
       for (int i=0; i<5; i++) rhs.zmien_element(0,i)=0;
}

tak może wyglądać ten konstruktor kopiujący? Jeśli nie, to nie bić, dopiero zagłębiam się w tajniki c++ ;)
I jeśli tak to jak potem tego użyć?

tak?

wektor wektor::operator=(wektor p)
{
       wektor temp_wektor(p);
       temp_wektor.zmien_rozmiar(p.zwroc_rozmiar()); 
       for(int i=0;i<roz;i++) temp_wektor.zmien_element(p.zwroc_element(i),i);
       getch();
       return temp_wektor;
}
0
wektor::wektor()
   :tab(NULL),roz(0)
{
}

wektor::wektor(const wektor &in)
   :tab(NULL),roz(0)
{
	*this=in;
}

wektor& wektor::operator=(const wektor &p)
{
	if(tab)delete tab;
	roz=p.roz;
	tab=new int[roz];
	memcpy(tab,p.tab,sizeof(int)*roz);
	return *this;
}
0
0x666 napisał(a)
wektor::wektor()
   :tab(NULL),roz(0)
{
}

wektor::wektor(const wektor &in)
   :tab(NULL),roz(0)
{
	*this=in;
}

wektor& wektor::operator=(const wektor &p)
{
	if(tab)delete tab;
	roz=p.roz;
	tab=new int[roz];
	memcpy(tab,p.tab,sizeof(int)*roz);
	return *this;
}

Hmm... tzn. może dodam jeszcze słowem (zapomnianego) wstępu - konstruktor został podany przez wykładowcę, czyżby w takim razie błędnie? (błądzić rzecz ludzka ;) ) Czy jest może sposób na zostawienie konstruktora takim jakim jest?
[b]0x666[/b] mógłbym prosić o wyjaśnienie?

0

To co podałem to tylko przykład. W takiej formie:

wektor::wektor()
{
       roz=5;
       tab=new int[roz];
       for (int i=0; i<5; i++) tab[i]=0;
}

też może być. Ważne, żeby roz i tab były poprawnie zainicjowane/wyzerowane w konstruktorach.

PS. w konstruktorze kopiującym nie trzeba alokować pamięci, bo to zrobi operator=, ale przedtem tab musi być wyzerowany...

wektor& wektor::operator=(const wektor &p)
{
        if(tab)delete tab; //<--- ...bo inaczej będzie katastrofa :P
   ...
}

PS 2. Drobna modyfikacja

wektor& wektor::operator=(const wektor &p)
{
        if(roz!=p.roz)        
        {
            if(tab)delete tab;
            roz=p.roz;
            tab=new int[roz];
        }

        memcpy(tab,p.tab,sizeof(int)*roz);
        return *this;
}
0

ooo, wielkie dzięki :) pomogło.

Gdyby to wszystko było takie łatwe... to.. nie byłoby takie interesujące :D

Zatem kolejna kłoda pod nogami:

wektor wektor::operator+(wektor p)
{
       wektor temp_wekt;
       if (roz<p.roz)
       {
          temp_wekt.zmien_rozmiar(p.zwroc_rozmiar());
          for (int i=0;i<p.zwroc_rozmiar();i++) temp_wekt.zmien_element((p.zwroc_element(i)+tab[i]),i);
          getch();
          return temp_wekt;
       }
       else
       {
          temp_wekt.zmien_rozmiar(roz);
          for (int i=0;i<roz;i++) temp_wekt.zmien_element(p.zwroc_element(i)+tab[i],i);
          getch();
          return temp_wekt;
       }
}

wiadomo co to.
otóż, gdy wpisuję potem "y=x+z" gdzie z jest z góry zadeklarowane, a x jest owym x-em z poprzednich rozważań to...

  [Linker error] undefined reference to `wektor::wektor(wektor const&)' 
0

Musisz zdefiniować konstruktor kopiujący - zwracasz przez wartość.

PS. parametry przekazuj przez (const) referencję.

0

Zdefiniuj koń-struktor :
wektor(wektor const&)
dla swojej klasy ..

0

@kolejna kloda:
ciekawe, ze to wywalilo blad linkera.. wyglada na to ze w pliku .h mial inna sygnature niz w .cpp? sprawdz!
a sygnatura powinna zamiast
wektor wektor::operator+(wektor p)
wygladac tak:
wektor wektor::operator+(wektor const & p)

0

Aż się zarejestrowałem :P
Dzięki Panowie za pomoc.
Idziemy dalej:
w przypływie tych emocji trochę się pogubiłem.. więc jak mam konstruktor kopiujący


wektor& wektor::operator=(const wektor &p)
{
       if(roz!=p.roz)
       {
       if(tab) {delete tab;}
       roz=p.roz; tab=new int[roz];
       }
       memcpy(tab,p.tab,sizeof(int)*roz);
       getch();
       return *this;
}

czy muszę deklarować(?) konstruktor ? pogubiłem się trochę.. tak patrzę na listing i hm.. mam tam tylko w/w konstruktor :D

z góry dzięki za odp.</b>

0

więc jak mam konstruktor kopiujący

wektor& wektor::operator=(const wektor &p){...}

To nie jest konstruktor kopiujący, tylko operator przypisania. TU wszystko masz.

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