Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Problem z konstruktorem kopiujacym i przeciazeniem operatora.

Ostatnio zmodyfikowano 2015-11-30 10:01
Autor Wiadomość
Amervar
Temat założony przez niniejszego użytkownika
Problem z konstruktorem kopiujacym i przeciazeniem operatora.
» 2015-11-29 20:48:06
Witam, potrzebuje pomocy przy programie a dokladnie przy konstruktorze kopiujacym i przeciazeniem operatora +. Stworzony przeze mnie konstruktor kopiuje tylko 1 wartosc, chcialbym aby kopiowal wszystkie wartosci zapisane w tablicy. Przeciazony operator + ma dodawac do siebie odpowiadajace numery indeksow tablicy (boki) - znam dzialanie przeciazenia operatora, jednak w tym wypadku wszystkie pomysly konczyly sie fiaskiem. Prosze o pomoc

#include <iostream>
using namespace std;
class Figura{
    double *tab_liczb;
    double pole;
    double obwod;
public:
    int ilosc_bokow;
    static int licznik;
    Figura(int ilosc_bokow)
    {
        tab_liczb = new double [ilosc_bokow];
        cout << "Podaj dlugosc bokow, wpisywanie do tablicy: " << endl;
        for (int i = 0; i < ilosc_bokow; i++)
            cin >> tab_liczb;
        licznik++;
        obliczanie(ilosc_bokow);
    }
    ~Figura()
    {
        delete [] tab_liczb;
        licznik--;
        cout << "U, ilosc: " << licznik << endl;
    }
    Figura (const Figura &obiekt) // KOPIUJE TYLKO 1 WARTOSC
    {
        for (int i = 0; i < 3; i++)
            this->tab_liczb = new double (*(obiekt.tab_liczb));
            //this->pole = obiekt.pole;
            //cout << obiekt.pole;
            cout << *(obiekt.tab_liczb);
    }
    void obliczanie(int ilosc_bokow);
    friend istream& operator>>(istream &wpisz, Figura &obiekt); // OK
    friend ostream& operator<<(ostream &wypisz, Figura &obiekt); // OK


};
istream & operator>>(istream &wpisz, Figura &obiekt)
{
    for (int i = 0; i < 3; i++)
        wpisz >> obiekt.tab_liczb;
    return wpisz;
}
ostream & operator<<(ostream &wypisz, Figura &obiekt)
{
    for (int i = 0; i < 3; i++)
        wypisz << obiekt.tab_liczb;
    return wypisz;
}
int Figura::licznik = 0;
void Figura::obliczanie(int ilosc_bokow) // Obliczanie obwodu i pola
{
    obwod = 0;
    pole = 0;
    for (int i = 0; i < ilosc_bokow; i++)
        obwod = obwod + tab_liczb;
        cout << "Obwod wynosi: " <<  obwod << endl;
    if(ilosc_bokow == 3) // obliczanie pola, wzor Heroda (polowa obwodu)
    {
        if(tab_liczb[0]+tab_liczb[1]>tab_liczb[2])
        {
            pole=(tab_liczb[0]+tab_liczb[1]+tab_liczb[2])/2;
            cout << "Pole wynosi: " << pole << endl;
        }
        else if(tab_liczb[0]+tab_liczb[2]>tab_liczb[1])
        {
            pole=(tab_liczb[0]+tab_liczb[1]+tab_liczb[2])/2;
            cout << "Pole wynosi: " << pole << endl;
        }
        else if(tab_liczb[2]+tab_liczb[1]>tab_liczb[0])
        {
            pole=(tab_liczb[0]+tab_liczb[1]+tab_liczb[2])/2;
            cout << "Pole wynosi: " << pole << endl;
        }
        else{ cout << "Blad" << endl;}
    }
    else{ cout << "Blad" << endl;}
}
int main()
{
    Figura f1(3);
    Figura f2(3);
    Figura f3(f1);
    cout << "Wpisz liczby do tablicy: " << endl;
    cin >> f1;
    cout << "Oto one: " << endl;
    cout << f1;
    return 0;
    //system ("PAUSE");
}
P-141123
ArgonZapan
» 2015-11-29 22:53:53
C/C++
for( int i = 0; i < 3; i++ )
     this->tab_liczb = new double( *( obiekt.tab_liczb ) );
//this->pole = obiekt.pole;
//cout << obiekt.pole;
cout << *( obiekt.tab_liczb );

1. Nie mam przy sobie żadnego kompilatora niestety, ale powinno to bardziej wyglądać tak

C/C++
this->ilosc_bokow = obiekt.Ilosc_bokow;
this->tab_liczb = new double[ this->ilosc_bokow ];
for( int i = 0; i < ilosc_bokow; i++ )
     this->tab_liczb[ i ] = obiekt.tab_liczb[ i ];

cout << tab_liczb[ i ];

2. W konstruktorze zapomniałeś zapisać wartości przekazywanej do zmiennej ilosc_bokow.
Bo jak stworzysz już tablice w pierwszym obiekcie, to przy kopiowaniu do drugiego obiektu, nie wiadomo jak wielką stworzyć tablice boków.
3. Przypomnij sobie zasady hermetyzacji
EDIT:
4. Następnym razem wrzuć kod w [.cpp][./cpp] (bez kropek)
P-141136
Amervar
Temat założony przez niniejszego użytkownika
» 2015-11-30 06:43:38
Dzięki za wytłumaczenie :)
Konstruktor kopiujący:
C/C++
Figura( const Figura & obiekt )
{
    this->ilosc_bokow = obiekt.ilosc_bokow;
    this->tab_liczb = new double[ 3 ];
    for( int i = 0; i < 3; i++ )
         this->tab_liczb[ i ] = obiekt.tab_liczb[ i ];
   
    cout << "Dziala konstruktor kopiujacy, oto wartosci: " << obiekt.tab_liczb[ 0 ]
    << obiekt.tab_liczb[ 1 ] << obiekt.tab_liczb[ 2 ] << endl;
}
Musiałem zamienić ilosc_bokow przy dynamicznej alokacji i w pętli na liczbę 3 bo wyskakiwały błędy.
Przeciążony operator:
C/C++
Figura operator +( Figura & obiekt )
{
    Figura pom;
    for( int i = 0; i < 3; i++ )
         pom.tab_liczb[ i ] = tab_liczb[ i ] + obiekt.tab_liczb[ i ];
   
    cout << "Oto wartosci po dodaniu: " << pom.tab_liczb[ 0 ] << pom.tab_liczb[ 1 ] << pom.tab_liczb[ 2 ] << endl;
    return pom;
}
Ta sama sytuacja co powyżej, wszelkie próby odniesienia się do ilosc_bokow powodowały błedy. Prosiłbym kogoś o pomoc z tym, ponieważ chciałbym w przeciążeniu operatora dodać instrukcje warunkowe uzupełniające liczbą np. 0 brakujące boki (jeżeli liczba boków figur się nie zgadza).
Ostatnie pytanie, dlaczego w Code Block'sie program działa bez zarzutów, wykonuje wszystkie instrukcje prawidłowo a w Visual Studio kompilator po dodaniu obiektów używa konstruktora kopiującego w stosunku do obiektu zwracanego (pom) w przeciążeniu operatora?
Cały kod:
C/C++
#include <iostream>
using namespace std;
class Figura {
    double * tab_liczb;
    double pole;
    double obwod;
public:
    int ilosc_bokow;
    static int licznik;
    Figura()
    {
        ilosc_bokow = 3;
        tab_liczb = new double[ ilosc_bokow ];
        for( int i = 0; i < ilosc_bokow; i++ )
             tab_liczb[ i ];
       
    }
    Figura( int ilosc_bokow )
    {
        tab_liczb = new double[ ilosc_bokow ];
        cout << "Podaj dlugosc bokow, wpisywanie do tablicy: " << endl;
        for( int i = 0; i < ilosc_bokow; i++ )
             cin >> tab_liczb[ i ];
       
        licznik++;
        obliczanie( ilosc_bokow );
    }
    ~Figura()
    {
        delete[] tab_liczb;
        licznik--;
        cout << "U, ilosc: " << licznik << endl;
    }
    Figura( const Figura & obiekt )
    {
        this->ilosc_bokow = obiekt.ilosc_bokow;
        this->tab_liczb = new double[ 3 ];
        licznik++;
        for( int i = 0; i < 3; i++ )
             this->tab_liczb[ i ] = obiekt.tab_liczb[ i ];
       
        cout << "Dziala konstruktor kopiujacy, oto wartosci: " << obiekt.tab_liczb[ 0 ]
        << obiekt.tab_liczb[ 1 ] << obiekt.tab_liczb[ 2 ] << endl;
    }
    Figura operator +( Figura & obiekt )
    {
        Figura pom;
        licznik++;
        for( int i = 0; i < 3; i++ )
             pom.tab_liczb[ i ] = tab_liczb[ i ] + obiekt.tab_liczb[ i ];
       
        cout << "Oto wartosci po dodaniu: " << pom.tab_liczb[ 0 ] << pom.tab_liczb[ 1 ] << pom.tab_liczb[ 2 ] << endl;
        return pom;
    }
    void obliczanie( int ilosc_bokow );
    friend istream & operator >>( istream & wpisz, Figura & obiekt ); // OK
    friend ostream & operator <<( ostream & wypisz, Figura & obiekt ); // OK
   
   
};
istream & operator >>( istream & wpisz, Figura & obiekt )
{
    for( int i = 0; i < 3; i++ )
         wpisz >> obiekt.tab_liczb[ i ];
   
    return wpisz;
}
ostream & operator <<( ostream & wypisz, Figura & obiekt )
{
    for( int i = 0; i < 3; i++ )
         wypisz << obiekt.tab_liczb[ i ];
   
    return wypisz;
}
int Figura::licznik = 0;
void Figura::obliczanie( int ilosc_bokow ) // Obliczanie obwodu i pola
{
    obwod = 0;
    pole = 0;
    for( int i = 0; i < ilosc_bokow; i++ )
         obwod = obwod + tab_liczb[ i ];
   
    cout << "Obwod wynosi: " << obwod << endl;
    if( ilosc_bokow == 3 ) // obliczanie pola, wzor Heroda (polowa obwodu)
    {
        if( tab_liczb[ 0 ] + tab_liczb[ 1 ] > tab_liczb[ 2 ] )
        {
            pole =( tab_liczb[ 0 ] + tab_liczb[ 1 ] + tab_liczb[ 2 ] ) / 2;
            cout << "Pole wynosi: " << pole << endl;
        }
        else if( tab_liczb[ 0 ] + tab_liczb[ 2 ] > tab_liczb[ 1 ] )
        {
            pole =( tab_liczb[ 0 ] + tab_liczb[ 1 ] + tab_liczb[ 2 ] ) / 2;
            cout << "Pole wynosi: " << pole << endl;
        }
        else if( tab_liczb[ 2 ] + tab_liczb[ 1 ] > tab_liczb[ 0 ] )
        {
            pole =( tab_liczb[ 0 ] + tab_liczb[ 1 ] + tab_liczb[ 2 ] ) / 2;
            cout << "Pole wynosi: " << pole << endl;
        }
        else { cout << "Blad" << endl; }
    }
    else { cout << "Blad" << endl; }
}
int main()
{
    Figura f1( 3 );
    Figura f2( 3 );
    Figura f3( f2 );
    f2 = f2 + f1;
    cout << "Wpisz liczby do tablicy: " << endl;
    cin >> f1;
    cout << "Oto one: " << endl;
    cout << f1;
    return 0;
    //system ("PAUSE");
}
P-141143
carlosmay
» 2015-11-30 07:41:32
Musiałem zamienić ilosc_bokow przy dynamicznej alokacji i w pętli na liczbę 3 bo wyskakiwały błędy.
 Jakie błędy?

Ostatnie pytanie, dlaczego w Code Block'sie program działa bez zarzutów, wykonuje wszystkie instrukcje prawidłowo a w Visual Studio kompilator po dodaniu obiektów używa konstruktora kopiującego w stosunku do obiektu zwracanego (pom) w przeciążeniu operatora?
 Czy wyniki końcowe są inne?
Standard nie określa zachowania jak kompilator ma zwracać obiekt.
P-141144
Amervar
Temat założony przez niniejszego użytkownika
» 2015-11-30 07:58:08
Z code blocksa:
terminate called after throwing an instane of bad_alloc
W VS program działa do końca a na końcu wyskakuje błąd Debug Assertion Failed (Expression: block type is valid)
P-141145
j23
» 2015-11-30 10:01:22
C/C++
Figura()
{
    ...
    for( int i = 0; i < ilosc_bokow; i++ )
         tab_liczb[ i ]; //<--- WTF?
   
}

Główny błąd:
C/C++
Figura( int ilosc_bokow )
{
    tab_liczb = new double[ ilosc_bokow ];
    ...
}
W tym konstruktorze powinieneś ustawić pole Figura::ilosc_bokow, nie robisz tego, pole ma wartość przypadkową, a co za tym idzie próba alokacji tablicy o np. ujemnej wartości będzie skutkować wyjątkiem bad_alloc.

P-141151
« 1 »
  Strona 1 z 1