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

[C++] Problemy z konstruktorem kopiującym i operatorem przypisania

Ostatnio zmodyfikowano 2013-06-22 09:42
Autor Wiadomość
fxbobi
Temat założony przez niniejszego użytkownika
[C++] Problemy z konstruktorem kopiującym i operatorem przypisania
» 2013-06-22 09:06:56
C/C++
#include <iostream>
#include <conio.h>
using namespace std;
class Wielokat
{
    int l_bokow; // liczba boków
    int * boki; // tablica z d³ugoœciami boków
public:
    Wielokat(); // konstruktor domyœlny
    Wielokat( int ll_bokow ); // konstruktor, gdy podana liczba boków
    Wielokat( const Wielokat & w ); // konstruktor kopiuj¹cy
    ~Wielokat(); // destruktor
   
    Wielokat::Wielokat & operator =( const Wielokat & w )
    {
        delete[] boki;
        boki = new int[ w.l_bokow ];
        l_bokow = w.l_bokow;
        for( int unsigned i = 0; i < l_bokow; i++ )
        {
            boki[ i ] = w.boki[ i ];
        }
    }
    // wstawianie dlugoœci boku
    void wpiszBok( int ktory, int dlugosc );
    // wyœwietlanie boków
    void print();
    // obliczanie obwodu
    int obwod();
    // w wersji obecnej: wyœwietlanie komunikatu
    // "Nie potrafie policzyc powierzchni"
    int area();
};

Wielokat::Wielokat()
{
    boki = new int[ 3 ];
    boki[ 0 ] = 0;
    boki[ 1 ] = 0;
    boki[ 2 ] = 0;
    l_bokow = 2;
}

Wielokat::Wielokat( int ll_bokow )
{
    boki = new int[ ll_bokow ];
    //new (boki) int [ll_bokow];
    try
    {
       
        if( ll_bokow < 0 )
        {
            throw( 1 );
        }
        else
        {
            l_bokow = ll_bokow;
            for( int unsigned i = 0; i < l_bokow; i++ )
            {
                boki[ i ] = 0;
            }
        }
    }
    catch( int unsigned e )
    {
        if( e == 1 )
        {
            cout << "L bokow nie moze byc ujemna";
        }
    }
}

Wielokat::Wielokat( const Wielokat & w )
{
    delete[] boki;
    l_bokow = w.l_bokow;
    for( int unsigned i = 0; i < l_bokow; i++ )
    {
        boki[ i ] = w.boki[ i ];
    }
}
Wielokat::~Wielokat()
{
    delete & l_bokow;
    delete[] boki;
   
}

void Wielokat::wpiszBok( int ktory, int dlugosc )
{
    try
    {
        if( ktory < 1 || dlugosc < 0 || ktory > l_bokow + 1 )
        {
            throw( 1 );
        }
        else
        {
            boki[ ktory ] = dlugosc;
        }
    }
    catch( int unsigned e )
    {
        if( e == 1 )
        {
            cout << "Podane parametry sa niepoprawne.";
        }
       
    }
}
void Wielokat::print()
{
    for( int unsigned i = 0; i < l_bokow; i++ )
    {
        cout << "Bok nr: " << i + 1 << " = " << boki[ i ] << endl;
       
    }
}

int Wielokat::obwod()
{
    int unsigned suma = 0;
    try
    {
        for( int unsigned i = 0; i < l_bokow; i++ )
        {
            if( boki[ i ] == 0 )
            {
                throw( 1 );
            }
            else
            {
                suma += boki[ i ];
            }
        }
       
    }
    catch( int unsigned e )
    {
        if( e == 1 )
        {
            cout << "\nJedena lub wiele dlugosci wielokata nie zostala okreslona ( jest rowna 0)";
        }
    }
    return( suma );
}
int Wielokat::area()
{
    cout << "w wersji obecnej: wyœwietlanie komunikatu\n"
    << "Nie potrafie policzyc powierzchni";
    return( true );
}
int main()
{
    Wielokat a;
    //a.print();
    //Wielokat c(1);
    //Wielokat b = Wielokat(3); // Wielokat b(3)
    //Wielokat c = a;
   
    return( 0 );
}
-----------------------------------------------------------------------------
Jesli utworze Wielokat A wszystko jest ok ,  jak odkomentuje linijke z Wielokat C(1) to pojawia sie komunikat ze probram przestał dzialac . (ten Windowsowy komunikat - o pomocy online)

Nie wiem dlaczego nie moge utworzyc 2 obiektow tej samej klasy , czy jest to wynik blednie napisanego programu czy cos nie tak z systemem.

Dodam że uzywam CodeBloc ale problem pojawia sie rownie na DevC++[/i]
P-85930
Monika90
» 2013-06-22 09:12:47
delete & l_bokow;
l_bokow nie było alokowane za pomocą new wiec nie używaj delete.

Konstruktor kopiujący też jest błędny i operator przypisania też, sposób w jaki używasz wyjątków też zły.
P-85931
fxbobi
Temat założony przez niniejszego użytkownika
» 2013-06-22 09:15:26
No tak , dzieki
P-85932
fxbobi
Temat założony przez niniejszego użytkownika
» 2013-06-22 09:18:12
A co jest nie tak z konstruktorem  , operatorem przypisania.

Czy w przypadku konstruktora kopiujacego powiniennem utworzyc odpowiednie metody które zwracały by dane  , a nie abym te dane bezpośrednio pobierał ?
P-85933
Monika90
» 2013-06-22 09:24:05
Twój operator przypisania nie zadziała prawidłowo w przypadku self-assignment, czyli:
C/C++
Wielokat w;
w = w;

Konstruktor kopiujący robi
delete[] boki;
, a raczej powinien robić new.

Czy w przypadku konstruktora kopiujacego powiniennem utworzyc odpowiednie metody które zwracały by dane  , a nie abym te dane bezpośrednio pobierał?
Nie. Konstruktor kopiujący ma dostęp do prywatnych składowych klasy i powinien z nich skorzystać.
P-85934
fxbobi
Temat założony przez niniejszego użytkownika
» 2013-06-22 09:30:43
Dziękuje , no tutaj zapomnialem dodać New dla konstruktora kopiujacego .
A dodaje tego Delete do kopiujacego aby zwolnic pamieć.

W przypadku gdy w=w to musial bym sprawdzić czy this==w. ( nie zwróciłem na to uwagi)

Pozdrawiam
P-85935
Monika90
» 2013-06-22 09:42:30
A dodaje tego Delete do kopiujacego aby zwolnic pamieć.
Ale jaką pamięć? Konstruktor kopiujący ma utworzyć nowy obiekt będący niezależną kopią już istniejącego. On nie ma zwalniać pamięci, on ma pamięć przydzielić.

Nie wiem po co piszesz tę klasę, ale w większości wypadków zamiast
new T[ n ]
 należy użyć
std::vector < T >
. Dzięki temu kompilator automatycznie wygeneruje operator=, konstruktor kopiujący i destruktor i unikniesz tych wszystkich problemów które masz.
P-85936
« 1 »
  Strona 1 z 1