Lista jednokierunkowa - programowanie obiektowe

0

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

#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

#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

//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

//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;
		
};
//--------------------------------------------------------
0
nazwa = new char [strlen(nazwa)+1];

Popraw sobie tę linijkę w funkcji operator= w klasie figura (mierzysz długość nieistniejącego łańcucha).

void opis(ostream& out) const
{
                cout<<"prostokat
}

W tym wypadku wypisuj do ogólnego strumienia wyjścia (out) strumienia pokazywanego przez out a nie do cout. Dzięki temu będzie można będzie wypisywać nie tylko na konsolę, ale również np. do pliku.

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.

Okno jest listą węzłów. Węzeł przechowuje wartość (w tym wypadku wskaźnik na figurę) i wskaźnik do następnego węzła. Składowa r (głowa) powinna pokazywać na początek listy. W przypadku listy pustej r pokazuje na zero. Przy wstawieniu na początek tworzysz nowy węzeł tak, aby pokazywał na dotychczasowy początek, a następnie przestawiasz głowę r na nowy początek i zwiększasz licznik węzłów. Jeśli nie udaje się utworzyć nowego węzła, to z listą nie robisz nic i zwracasz false, w przeciwnym wypadku zwracasz true.
Co do funkcji "kopia", to możesz użyć jawnego wywołania konstruktora kopiującego. Przy usuwaniu usuwasz kolejne węzły po kolei.

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().

Co do operatora[], to ustawiasz wskaźnik na głowę i przesuwasz go w pętli na kolejne węzły (każdy węzeł ma wskaźnik na następny węzeł) inkrementując licznik pętli.
Jak licznik doliczy do właściwej wartości, to zwracasz wskaźnik na figure pokazywaną przez aktualny węzeł.
Co do funkcji pole_okna, to "nawigujesz" po figurach listy przy pomocy operatora[] i dla każdej figury dodajesz jej pole do pola całkowitego (o ile chodzi tu po prostu o sumowanie pól). Gdyby pole_okna była zaprzyjaźniona z klasą okno, to można by bylo zrobić to wydajniej.

Na temat list, czy to jedno- czy dwukierunkowych znajdziesz mnóstwo informacji zarówno w sieci jak i na tym forum.

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