Ćwiczenie 1
1
Definiowanie prostych klas
Ćwiczenie to poświęcone jest poznaniu podstawowych zagadnień związanych z definiowaniem prostych klas. Obejmuje m.in. ćwiczenia pozwalające opanować definiowanie konstruktorów, funkcji składowych spełniających rolę akcesorów i realizatorów. Ćwiczenie obejmuje również poznanie podstawowych możliwości obiektowej biblioteki strumieniowej oraz predefiniowanych obiektów cout i cin. Materiał teoretyczny, niezbędny dla zrozumienia prezentowanych przykładów zawierają materiały wykładowe dostępne online, w postaci dokumentu pdf, pod adresem: http://zsi.tech.us.edu.pl/~romek/dyd/pjp/pjp_cxx.pdf. Biblio-teka strumieniowa: str. 5-8, informacje dotyczące klas i obiektów: str. 9-20.
1.1 Krok pierwszy
Należy napisać obiektową wersję programu pozwalającego na obliczanie pola kwadratu. Program pozwala na wprowadzenie liczby rzeczywistej reprezentującej bok kwadratu, oblicza jego pole i wyprowadza do strumienia wyjściowego programu.
Obliczenia ma realizować obiekt reprezentujący kwadrat. Niech obiekt nazywa się
s, i należy do klasy Square. Przykładowy kod funkcji main może mieć następującą postać:
int main() {
double num; Square s;
cout << endl << "Obliczam pole kwadratu" << endl; cout << "Podaj bok: ";
cin >> num;
s.setSide( num );
cout << "Pole kwadratu wynosi: " << s.area(); return 0;
}
Definiowanie prostych klas
Funkcja składowa setSide umożliwia ustalenie długości boku obiektu s. Funkcja
area pozwala na obliczenie pola. Program należy oczywiście uzupełnić o włączenie
odpowiednich plików nagłówkowych oraz definicję klasy Square. Warto również przed zakończeniem programu wstawić sekwencję zatrzymująca jego wykonanie, tak, aby wyniki jego działania były widoczne. Kompletny program — nie zawierający jednak konstruktorów — zawiera przedstawiony dalej kod źródłowy.
#include <iostream> using namespace std; class Square
{
public :
void setSide( double side ); double getSide();
double area(); private:
double side; };
void Square::setSide( double side ) { Square::side = side; } double Square::getSide() { return side; } double Square::area() {
return side * side; }
int main() {
double num; Square s;
cout << endl << "Obliczam pole kwadratu" << endl; cout << "Podaj bok: ";
cin >> num;
s.setSide( num );
cout << "Pole kwadratu wynosi: " << s.area(); cin.ignore();
cin.get(); return 0; }
Przedstawioną powyżej klasę Square należy rozszerzyć o konstruktor domyślny. Zobacz str. 13 materiałów wykładowych.
1.2 Krok drugi
Rozszerzyć program o możliwość obliczania pól innych figur: • prostokąta,
• trójkąta, • okręgu, • trapezu.
Dla każdej z figur należy zdefiniować odpowiednią klasę: Rectangle, Triangle, itp.. Funkcję main należy rozbudować o proste menu pozwalające na wybranie typu
figury. Szablon takiego rozwiązania zawiera przedstawiony dalej kod źródłowy.
int main() {
char c;
cout << endl << "Wybierz figure:" << endl; cout << "1.Kwadrat\n2.Prostokat\n3.Trojkat\n>"; cin >> c;
switch( c ) {
case '1' : cout << "Obliczenia dla kwadratu" << endl; // ...
break;
case '2' : cout << "Obliczenia dla prostokata" << endl; // ...
break;
case '3' : cout << "Obliczenia dla trojkata" << endl; // ... break; } cin.ignore(); cin.get(); return 0; }
Aby umożliwić wielokrotne wykonywanie obliczeń bez konieczności powtórnego uruchamiania programu, można go rozbudować o iterację, co ilustruje przedstawiony dalej kod źródłowy. Oczywiście menu programu należy rozbudować o opcję — np. identyfikowaną przez kolejny numer — pozwalającą na wybranie zakończenia programu.
. . . do {
cout << endl << "Wybierz figure:" << endl;
cout << "1.Kwadrat\n2.Prostokat\n3.Trojkat\n4.Koniec\n>"; cin >> c;
switch( c ) {
case '1' : cout << "Obliczenia dla kwadratu" << endl; // ...
break;
case '2' : cout << "Obliczenia dla prostokata" << endl; // ...
break;
case '3' : cout << "Obliczenia dla trojkata" << endl; // ... break; } } while( c != '4' ); . . .
1.3 Krok trzeci
Program w wersji dla kilku figur się rozrasta, rozrasta się również jego funkcja
main. Można oczywiście podzielić program na funkcje… ale nasz program zacznie wtedy być hybrydą proceduralno-obiektową! Proponuję wprowadzić obiekt, który będzie reprezentował nasz program. Niech obiekt nazywa się myProg a jego klasa
Program. Przykład funkcji main wykorzystującej taki obiekt może wyglądać
następująco: int main() { Program myProg; myProg.run(); return 0; }
Definicja klasy Program:
class Program { public : Program(); void run(); void squareArea(); void rectangleArea(); void triangleArea(); };
Implementacja funkcji składowych:
Program::Program() {
cout << endl << "Program obliczający pola figur" << endl; } void Program::run() { char c; do {
cout << endl << "Wybierz figure:" << endl;
cout << "1.Kwadrat\n2.Prostokat\n3.Trojkat\n4.Koniec\n>"; cin >> c; switch( c ) { case '1' : squareArea(); break; case '2' : rectangleArea(); break; case '3' : triangleArea(); break; } } while( c != '4' ); } void Program::squareArea() {
cout << "Obliczenia dla kwadratu" << endl; // ...
}
void Program::rectangleArea() {
cout << "Obliczenia dla prostokata" << endl; // ...
}
void Program::triangleArea() {
cout << "Obliczenia dla trojkata" << endl; // ...
}
1.4 Krok czwarty i ostatni
W oparciu o przedstawione w poprzednich punktach przykłady należy opracować program, obliczający pola figur (kwadrat, prostokąt, koło, trójkąt, trapez). Program
ma wyświetlać menu umożliwiające wybór figury, po dokonaniu tego wyboru program wczytuje niezbędne dane, wyświetla wyniki, po czym wraca do menu umożliwiając dokonanie powtórnych obliczeń. Każda figura posiada klasę reprezentującą ją w programie, wszelkie obliczenia realizowane są przy wykorzystaniu funkcji składowej area każdej z klas. Obliczenie nadzoruje klasa reprezentująca program, przybierając postać podobna do klasy Program.
1.5 Co po tym ćwiczeniu należy umieć?
Zakładam, że po tym ćwiczeniu każdy potrafi odpowiedzieć na pytanie:1. Co to jest obiekt a co to jest klasa? 2. Co to jest pole i funkcja składowa?
3. Jakie są reguły dostępu do składowych public a jakie do składowych
private?
4. Co to jest konstruktor i do czego służy?
5. Co to jest konstruktor domyślny, kiedy jest aktywowany i jak się go deklaruje?
6. Co to jest konstruktor ogólny, kiedy jest aktywowany i jak się go deklaruje? 7. Co to są akcesory, realizatory i do czego służą?
Zakładam również, że każdy potrafi napisać od podstaw klasę o stopniu skomplikowania zbliżonym do przećwiczonych klas reprezentujących figury, oraz że każdy wie jak wyprowadzać dane z wykorzystaniem strumienia cout i wczytywać dane z wykorzystaniem strumienia cin.