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

[C++] Lista jednokierunkowa + zwracanie kilku wartości przez funkcję

Ostatnio zmodyfikowano 2013-05-26 02:44
Autor Wiadomość
Gadziu
Temat założony przez niniejszego użytkownika
[C++] Lista jednokierunkowa + zwracanie kilku wartości przez funkcję
» 2013-05-14 10:01:06
Witam,
mam problem ze zrobieniem zadania domowego. Może najpierw zacznijmy, że nie rozumiem polecenia. Studiuję matematykę,a nie informatykę, a nasz prowadzący, albo nie chcę, albo nie umiem przekazać nam jakiejkolwiek wiedzy, więc naprawdę nikt u nas tego nie czai. Treść zadanie jest następująca:
Zadanie jest podzielone na 3 etapy.
ETAP 1 (2 pkt): klasa figura – 1 pkt; klasy pochodne – 1 pkt
Należy zaimplementować klasę bazową figura, klasy pochodne kolo i prostokąt, oraz kwadrat (jako pochodna klasy prostokąt).
Potrzebne definicje metod i operatorów zapisz bezpośrednio w definicji klasy w pliku figury.h (nie twórz odrębnych plików implementacyjnych).
Nie wolno zmieniać użytych w programie nazw pól i metod, ani zasad ich dostępności ( public, protected, private ). Nie wolno modyfikować treści funkcji main().
W klasach pochodnych zaimplementuj TYLKO niezbędne składowe tak, by uzyskać sposób działania zgodny z zawartością pliku tekstowego wyniki.txt.
ETAP 2 (2 pkt)
Zaimplementuj klasę okno do przechowywania danych o typie figura*. Klasa okno reprezentuje listę jednokierunkową z możliwością wstawiania kolejnych elementów na początek listy.
W celu poprawnego (niezależnego) przechowywania danych w liście, uzupełnij klasy figur w wirtualną metodę kopia, która powinna zwracać wskaźnik do odpowiedniej kopii danych (zgodnej z typem kopiowanego obiektu). Metoda ta jest wykorzystywana w konstruktorze struktury el.
ETAP 3 (1 pkt)
Uzupełnij definicję klasy okno o następujące metody:
figura* operator[](int i) const; //zwraca adres elementu o indeksie i (0<=i<ile)
int rozmiar() const; //zwraca liczbę elementów listy
Zaimplementuj funkcję pole_okna, która dla obiektu L klasy okno, znajduje całkowite pole jego elementów P oraz indeks jmax elementu o polu maksymalnym:
int jmax;
double P=pole_okna(L,jmax);
Funkcję zaimplementuj w pliku przed funkcją main().


Etap pierwszy zrobiłem i nawet działa (o dziwo...), ale jeśli chodzi o etap 2 i 3 to nawet nie wiem tak naprawdę co mam zrobić. Mógłby mi ktoś najpierw jak krowie na miedzy wytłumaczyć co mam zrobić? Mam dane już trochę zrobione pliki. Main'a nie możemy edytować.
main.cpp
C/C++
#include <iostream>
using namespace std;
#include "figury.h"
#include "okno.h"

//w etapie 3 tutaj napisz implementację funkcji pole_okna

int main()
{
    // ETAP 1 (2 pkt): klasa figura - 1 pkt, wszystkie klasy pochodne - 1 pkt
   
    {
        prostokat P1( "P1", 5, 10 );
        prostokat P2( "P2", 6, 11 );
        kwadrat K1( "K1", 6 );
        kolo O1( "O1", 10 );
       
        cout << endl << "-----------------------------------" << endl;
       
        figura * FIG[ 4 ] = { & P1, & P2, & K1, & O1 };
       
        for( int i = 0; i < 4; i++ ) cout << * FIG[ i ] << endl;
       
        cout << endl << "-----------------------------------" << endl;
       
        prostokat P3 = P1;
        cout << P1;
        cout << P3;
        cout << endl << "-----------------------------------" << endl;
       
        P1 = P2;
        cout << P2;
        cout << P1;
        cout << endl << "-----------------------------------" << endl;
       
        kwadrat Kwa[ 3 ] = { kwadrat( "K10", 10 ), kwadrat( "K11", 20 ), };
        cout << endl;
       
    }
   
    //ETAP 2 (2 pkt)
   
    cout << endl << "OKNO-----------------------------------" << endl;
   
   
    //figura* fig[3];
    //fig[0] = new prostokat("dP5",1,2);
    //fig[1] = new kwadrat("dK3",9);
    //fig[2] = new kolo("dO2",3);
   
    //okno L;
   
    //for (int i=0;i<3;i++) L.wstaw(fig[i]);
    //
    //for( int i=0; i<3; i++ ) delete fig[i];
    //
    //cout<<endl<<"Elementy okna:"<<endl<<L<<endl;
   
   
    //ETAP 3 (1 pkt)
    /*
    cout<<endl<<"-----------------------------------"<<endl;
   
    int jmax;
    double P=pole_okna(L,jmax);
   
    cout<<"Pole okna: "<<P<<endl;
   
    if (jmax>=0)
    cout<<"Element o maksymalnym polu jest na pozycji nr: "<<jmax+1<<endl;
    */
    cout << endl << "-----------------------------------" << endl;
   
    return 0;
}

figura.h
C/C++
#pragma once
#include <iostream>
#define _USE_MATH_DEFINES
#include <math.h>
using namespace std;

class figura
{
    char * nazwa;
   
public:
    figura( char * _nazwa = "" )
    {
        nazwa = new char[ strlen( _nazwa ) + 1 ];
        nazwa = strcpy( nazwa, _nazwa );
        cout << "+ tworzy figure o nazwie: " << nazwa << endl;
    }
    figura( const figura & fig )
    {
        nazwa = new char[ strlen( fig.nazwa ) + 1 ];
        nazwa = strcpy( nazwa, fig.nazwa );
        cout << "KOPIOWANIE: " << nazwa << " ";
        fig.opis( cout );
       
    }
    virtual ~figura()
    {
        cout << "- Usuwa figure o nazwie: " << nazwa << endl;
        cout << endl;
        delete[] nazwa;
    }
    figura & operator =( const figura & fig )
    {
        cout << "figura::operator=" << endl;
        if( this != & fig )
        {
            delete[] nazwa;
            nazwa = new char[ strlen( nazwa ) + 1 ];
            strcpy( nazwa, fig.nazwa );
        }
        return * this;
    }
    friend ostream & operator <<( ostream & out, const figura & fig )
    {
        out << "figura " << fig.nazwa << " i polu " << fig.pole() << "; ";
        fig.opis( out );
        return out;
    }
   
    virtual figura * kopia() = 0;
    virtual double pole() const = 0;
    virtual void opis( ostream & out ) const = 0;
   
   
};

class prostokat
    : public figura
{
protected:
    double a, b;
   
public:
   
    prostokat( char * n, double _a, double _b )
        : figura( n )
        , a( _a )
        , b( _b )
    {
        cout << "  jest to prostokat" << endl;
    }
   
   
    figura * kopia()
    {
        return 0;
    }
    double pole() const
    {
        return a * b;
    }
    void opis( ostream & out ) const
    {
        cout << "prostokat (" << a << "," << b << ")" << endl;
    }
    ~prostokat()
    {
        cout << "  usuwanie prostokata" << endl;
    }
};

class kwadrat
    : public prostokat
{
    //nie posiada żadnych pól
public:
   
    kwadrat( char * n = "KWADRAT", double _a = 5 )
        : prostokat( n, _a, _a )
    {
        cout << "  jest to kwadrat" << endl;
    }
    figura * kopia()
    {
        return 0;
    }
    double pole() const
    {
        return a * a;
    }
    void opis( ostream & out ) const
    {
        cout << "kwadrat (" << a << ")";
    }
    ~kwadrat()
    {
        cout << "  usuwanie kwadratu" << endl;
    }
   
};

class kolo
    : public figura
{
    double r;
   
public:
   
    kolo( char * n, double _r )
        : figura( n )
        , r( _r )
    {
        cout << "  jest to kolo" << endl;
    }
    figura * kopia()
    {
        return 0;
    }
    double pole() const
    {
        return M_PI * r * r;
    }
    void opis( ostream & out ) const
    {
        cout << "kolo [" << r << "]";
    }
    ~kolo()
    {
        cout << "  usuwanie kola" << endl;
    }
};

okno.cpp
C/C++
//okno.cpp
#include <iomanip>
#include "okno.h"

okno::okno()
{
    //uzupełnij
}

bool okno::wstaw( figura * _dane )
{
    //uzupełnij
    return true;
}

okno::~okno()
{
    //uzupełnij
}

ostream & operator <<( ostream & out, const okno & L )
{
    //uzupełnij
    return out;
   
}

okno.h
C/C++
//okno.h

#pragma once
#include <iostream>
using namespace std;
#include "figury.h"

struct el
{
    figura * dane;
    el * nast;
   
    el( figura * _dane, el * _nast )
        : nast( _nast )
    {
        //uzupełnij klase figura oraz klasy pochodne o odpowiednią wirtualną metodę kopia
        dane = _dane->kopia();
    }
    ~el()
    {
        delete dane;
    }
   
};

class okno
{
    el * r;
    int ile;
   
public:
    okno();
    ~okno();
    bool wstaw( figura * );
    friend ostream & operator <<( ostream & out, const okno & L );
   
    //uzupełnij w etapie 3
    //figura* operator[](int i) const;
    //int rozmiar() const;
   
};
P-82905
Monika90
» 2013-05-14 10:33:43
Tak z ciekawości zapytam, które fragmenty napisałeś ty, a które twój nauczyciel? Wg mnie jest to wszystko napisane w bardzo złym stylu. Np. funkcja
virtual figura * kopia() = 0;
 powinna mieć atrybut
const
. Podobnie w konstruktorze
figura( char * _nazwa = "" )
 powinno być
const char *
. I mnóstwo innych niezgrabnych rzeczy...

Przyznam, że nierozumiem po co w ogóle was uczą C++? Po co w ogóle uczą programowania na matematyce?
P-82906
Gadziu
Temat założony przez niniejszego użytkownika
» 2013-05-14 10:45:45
To wszystko co napisałaś już było, my mieliśmy to tylko uzupełnić. Po co? Sam do końca nie wiem, ale jest w tym jakiś zamysł podobnież, ponieważ po pierwsze to wydział matematyki i nauk informacyjnych jest, a po drugie w obecnych czasach praca matematyka często sprowadza się do tworzenia pewnych programów obliczeniowych. Ogólnie jako takiego programowania mam 3 semestry. Jeden już miałem i był prowadzony naprawdę super. Ale ten teraz to jest jakaś pomyłka normalnie...
P-82907
Monika90
» 2013-05-14 11:10:06
To powiedz nauczycielowi żeby dodał
const
 w tych miejscach o których mówiłam. Dostaniesz dodatkowe punkty za znalezienie błedu w zadaniu.

A jeżeli chodzi o etap 2, to masz prawie gotowe.
uzupełnij klasy figur w wirtualną metodę kopia
To nazywa się "virtual constructor idiom" i jest opisanu tu: http://www.parashift.com/c++-faq/virtual-ctors.html z tą różnicą, że zamiast kopia() jest clone().

Potem należy zaimplementować listę jednokierunkową, no to jest chyba banalne?
okno::okno()
 powinno inicjalizować składowe tak żeby lista była pusta.
bool okno::wstaw( figura * _dane )
 ma tworzyć nowy węzeł (obiekt typu
el
) i wstawić na początek listy.
okno::~okno()
pętla która niszczy wszystkie węzły.
ostream & operator <<( ostream & out, const okno & L )
pętla która wywołuje opis(out) albo operator << dla każdej figury na liscie.
P-82909
Gadziu
Temat założony przez niniejszego użytkownika
» 2013-05-14 11:32:02
Jak przy każdej klasie, czyli w prostokącie itd dodam np.
virtual prostokat * kopia() const = 0
 to wyskakuje mi błąd: error C2259: 'kolo' : cannot instantiate abstract class
P-82913
Monika90
» 2013-05-14 11:41:29
To nie dodawaj, przecież już masz w każdej klasie funkcję kopia, tylko masz wypełnić ją treścią, w środku zamiast retrun 0; ma być return new prostokat(*this); itp.
P-82914
Gadziu
Temat założony przez niniejszego użytkownika
» 2013-05-14 12:06:23
C/C++
okno::okno()
{
    r = NULL;
    ile = 0;
}
To chyba ok. Ale mam problem z tym następnym. Może jakaś podpowiedź?
A destruktor to chyba tak:
C/C++
okno::~okno()
{
    el * p;
    while( r )
    {
        p = r->nast;
        delete r;
        r = p;
    }
}
No wysiadam normalnie... Próbuje zrobić to wstaw, ale cały czas wywala mi złą alokacje pamięci. Już próbowałem różnych wersji. Teraz wygląda to tak:
C/C++
bool okno::wstaw( figura * _dane )
{
    r->dane = _dane;
    r->nast = NULL;
    ile++;
    return true;
}
P-82915
Monika90
» 2013-05-14 13:08:39
wstawianie na początek listy
C/C++
bool okno::wstaw( figura * _dane )
{
    el * nowy = new el( _dane, r );
    r = nowy;
    ile++;
    return true;
}
P-82916
« 1 » 2 3 4
  Strona 1 z 4 Następna strona