Klasa imitująca tablicę - błędne pzeładowanie operatorów

0

Kurczę, siedzę nad tym pół dnia i nie mogę sobie poradzić. Debugowałem, patrzyłem co jest nie tak i doszedłem tylko do wniosku, że wskaźnik jest po prostu gdzieś usuwany szybciej niż odczytywany, ale jak to naprawić to nie wiem. Poza tym może ten kod w ogóle jest do kitu napisany, proszę zobaczcie.
Ogólnie chodzi o operator +. Chciałbym móc dodawać tablice na zasadzie takiej, że do odpowiednich indeksów większej dodaję odpowiednie indeksy mniejszej, a nadwyżkę zostawiam po prostu. Operator += działa. Ale chodzi o to, żeby móc zapisać c=a+b.

Wrzucę może najbardziej pożądane fragmenty:
Tablice.cpp

#include <iostream>
#include "include/Tablica.h"

Tablica::Tablica(){
    rozmiar = 0;
    wsk = NULL;
}

Tablica::Tablica(int roz){
    rozmiar = roz;
    wsk = new int [rozmiar];
}

Tablica::Tablica(const Tablica& t){
    rozmiar = t.rozmiar;
    wsk = new int [rozmiar];
    for(int i=0;i<t.rozmiar;++i)
        wsk[i]=t.wsk[i];
}

Tablica::~Tablica(){
    delete[] wsk;
}






Tablica& Tablica::operator=(const Tablica& t){
    if(this->wsk != NULL)
        delete[] wsk;
    this->rozmiar = t.rozmiar;
    this->wsk = new int[rozmiar];
    for(int i=0;i<rozmiar;++i)
        this->wsk[i]=t.wsk[i];
    return *this;
}

Tablica& Tablica::operator+=(const Tablica& t){
    if(rozmiar<t.rozmiar){
        int* c = new int[t.rozmiar];
        for(int i=0;i<rozmiar;++i){
           c[i]=wsk[i]+t.wsk[i];
        }
        wsk=c;
    }
    else{
        for(int i=0;i<t.rozmiar;++i){
                wsk[i]+=t.wsk[i];
        }
        return *this;
    }
}

Tablica& Tablica::operator+(const Tablica& t){
    if(rozmiar<t.rozmiar){
        Tablica d(t);
        for(int i=0;i<t.rozmiar;++i){
           d.wsk[i]+=wsk[i];
        }
        return d;
    }
    else{
        Tablica d(*this);
        for(int i=0;i<t.rozmiar;++i){
            d.wsk[i]+=t.wsk[i];
        }
        return d;
    }

}

 
1

Nie analizowałem tego, ale jedna rzecz rzuca się w oczy:

Tablica& Tablica::operator+(const Tablica& t){
    // ...
        Tablica d(t);
        // ...
        return d;

Zwracasz referencję do obiektu istniejącego na stosie. Bez sensu. Powinieneś zwracać kopię - wywal referencję w typie zwracanym.

1

Zasada DRY się kłania:

//w klasie Tablica(size_t roz=0,int v=0)
Tablica::Tablica(size_t roz,int v):rozmiar(roz),wsk(new int[roz]) // int ? WTF? spodziewasz się ujemnych rozmiarów?
  {
   for(int i=0;i<rozmiar;++i) wsk[i]=v;
  }
 
Tablica::Tablica(const Tablica& t):rozmiar(t.rozmiar),wsk(new int[t.rozmiar]) 
  {
   for(int i=0;i<rozmiar;++i) wsk[i]=t.wsk[i];
  }
 
Tablica::~Tablica()
  {
   delete[] wsk;
  }
 
void Tablica::swap(Tablica& t)
  {
   ::swap(rozmiar,t.rozmiar);
   ::swap(wsk,t.wsk);
  }
 
Tablica &Tablica::operator=(const Tablica& t)
  {
   Tablica tmp(t);
   swap(t);
   return *this;
  }
 
Tablica Tablica::operator+(const Tablica &t)const
  {
   if(rozmiar>t.rozmiar)
     {
      Tablica tmp(*this);
      for(int i=0;i<rozmiar;++i) tmp.wsk[i]+=t.wsk[i];
      return tmp;
     }
   else
     {
      Tablica tmp(t);
      for(int i=0;i<rozmiar;++i) tmp.wsk[i]+=wsk[i];
      return tmp;
     }
  }
}
 
Tablica &Tablica::operator+=(const Tablica& t)
  {
   Tablica tmp(t+*this);
   swap(tmp);
  }

Uwaga pisano z palca

Pamiętam mniej kodu - mniejsza szansa na błąd.

0

Nie wprowadzając nowego kodu od @_13th_Dragon a poprawiając jedynie to co napisał @Endrju - program magicznie zaczął działać. A przysiągłbym, że próbowałem wcześniej zwracać kopię.
Mógłby ktoś wytłumaczyć mi dlaczego zwracanie referencji w tym miejscu jest złe?

1

Bo zwracasz referencje na lokalny obiekt który za chwile przestanie istnieć.

1
xorgx3 napisał(a):

Mógłby ktoś wytłumaczyć mi dlaczego zwracanie referencji w tym miejscu jest złe?

No bo obiekt d jest obiektem utworzonym na stosie. Po wyjściu z funkcji obiekt ten nie istnieje (wywołuje się Twój destruktor a potem obiekt jest usuwany ze stosu), a Ty masz referencję donikąd.

0

Za dużo myślenia na dziś. Przecież to oczywiste :) Dziękuję za pomoc, chociaż teraz aż mi głupio, że pytałem o taką prostą rzecz.

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