Wejściówka na ćwiczenia nr 12

Zaprojektuj i zaimplementuj cztery klasy, które na ćwiczeniach 12 posłużą jako klasy bazowe. Klasy reprezentują pojęcia:

  1. silnik samochodowy – zawiera pola przechowujące cechy wspólne dla wszystkich silników (moc, wymiary).
  2. samochód – zawiera pola przechowujące cechy wspólne dla wszystkich samochodów (cena, rodzaj silnika).
  3. urządzenie optyczne – zawiera pola przechowujące cechy wspólne dla wszystkich takich urządzeń (zoom, waga, typ matrycy: CCD lub CMOS).
  4. osoba na uczelni – zawiera pola przechowujące cechy wspólne dla wszystkich takich osób (imię i nazwisko, adres e-mail).

Wszystkie pola klasy bazowej powinny być zadeklarowane jako protected. Dla każdego z pól powinny istnieć odpowiednie getery i setery. Ponadto każda klasa musi mieć metodę wypisz, która wypisze w oknie konsoli wartości wszystkich pól.

Do wszystkich klas zaprojektuj po trzy konstruktory: konstruktor domyślny, kopiujący oraz z argumentami przechowującymi wartości dla inicjalizacji wszystkich pól.

Dodatkowo każda klasa bazowa powinna mieć jeszcze pole nast, zadeklarowane jako public i zawierające wskaźnik typu takiego jak klasa bazowa. Tym sposobem klasa bazowa będzie mogła być wykorzystana jako element listy dynamicznej jednokierunkowej.

Zademonstruj poprawność działania zaprojektowanych klas, pisząc w funkcji main kod, budujący dla każdego z typów danych listę dynamiczną jednokierunkową zawierającą 5 elementów. Do tworzenia elementów listy użyj konstruktorów domyślnych. Po utworzeniu każdej z list wywołaj metodę wypisz na rzecz każdego z elementów listy. Na koniec usuń wszystkie listy.

Wejściówka na ćwiczenia nr 10

Zaprojektuj klasę, która posłuży do tworzenia obiektów reprezentujących macierze przechowujące liczby rzeczywiste.

Klasa macierz posiada pola do zarządzania dwuwymiarową, dynamiczną tablicą reprezentującą komórki macierzy. Wszystkie pola są prywatne.

Posiada trzy konstruktory:

  1. domyślny, inicjalizujący wszystkie pola tak, aby powstała macierz o wymiarach 1 na 1; w tym przypadku nie powinny być alokowane żadne dodatkowe zmienne dynamiczne,
  2. konstruktor z argumentami opisującymi wymiary macierzy; wymiary mogą być dowolne większe od zera. Pamięć pod komórki macierzy powinna być alokowana dynamicznie. Przy okazji działania tego konstruktora przetestuj, jakie są górne granice dostępnej pamięci w twoim komputerze, tj. podając coraz większe wymiary macierzy doprowadź do sytuacji, kiedy alokacja pamięci w końcu nie powiedzie się. Zapisz uzyskane wartości graniczne, będą potrzebne na wejściówce,
  3. konstruktor kopiujący, który utworzy drugą macierz identyczną co do rozmiaru i zawartości.

Posiada też seter i geter do komórek macierzy. Obydwie metody powinny kontrolować poprawność argumentów wejściowych, tj. czy współrzędne żądanej komórki mieszczą się w dozwolonych granicach.

Dodatkowo posiada metodę, która realokuje rozmiar macierzy, tj. powiększa jej rozmiar lub pomniejsza. W przypadku pomniejszenia, część informacji zapisanej w komórkach macierzy jest tracona. W przypadku powiększenia nowo dodane komórki są zapełnianie wartością domyślną (dowolnie ustaloną).

Napisz prosty program testujący działanie wszystkich konstruktorów i metod klasy macierz. Utwórz obiekt z wykorzystaniem konstruktora domyślnego. Utwórz drugi obiekt reprezentujący macierz o dowolnym rozmiarze i zainicjuj go wartościami losowymi z przedziału (-1,1) (użyj do tego setera). Utwórz trzeci i czwarty, obydwa będące kopiami odpowiednio pierwszego i drugiego obiektu. Porównaj zawartość komórek miedzy oryginałami i kopiami (użyj do tego getera).

Pamiętaj, aby po zakończeniu korzystania z macierzy wszystkie sprowadzić do rozmiaru 1 na 1, tj. aby zwolnić wszystkie zmienne dynamiczne kontrolowane przez te obiekty.

Wejściówka na ćwiczenia nr 9

Zaprojektuj klasę, reprezentującą figurę na płaszczyźnie: trapez.

Zaproponuj zestaw pól dla tej klasy, pozwalający na jednoznaczne określenie jej położenia na płaszczyźnie względem początku układu współrzędnych oraz jednoznacznie określający jej rozmiary (np. długości boków, podstawy, itd.). Dla uproszczenia przyjmij, że trapez jest zawsze rysowany w określonej pozycji, np. podstawą równolegle do osi X. Projektując zestaw pól postaraj się zminimalizować ich liczbę. Np. gdyby to dotyczyło kwadratu, to do określenia położenia wystarczą współrzędne jednego z wierzchołków, np. lewy-dolny, a do określenia rozmiarów – długość jednego boku. Za pomocą tych wartości jesteśmy już w stanie łatwo wyznaczyć w kwadracie współrzędne wszystkich pozostałych wierzchołków oraz długości pozostałych boków.

Zbiór pól reprezentujących położenie trapezu powinien być rozłączny ze zbiorem pól reprezentujących jego rozmiary, tak aby ewentualne operacje zmiany położenia nie obejmowały modyfikacji pól rozmiaru, a np. skalowanie nie modyfikowało pól położenia.

Wszystkie pola mają być niedostępne z zewnątrz (zadeklarowane jako private).

Do klasy dodaj trzy metody zadeklarowane jako publiczne:

  1. Pierwsza – ma ustalać położenie i rozmiary figury, tj. modyfikować wartości pól opisujących położenie i rozmiar. Nowe wartości dla pól powinny być podawane w argumentach wywołania metody. Metoda powinna kontrolować poprawność wartości podawanych w argumentach wywołania i jeżeli są nieprawidłowe (np. ujemne długości boków) powinna je zastępować bezpiecznymi wartościami domyślnymi.
  2. Druga – powinna wypisywać wartości wszystkich pól figury w oknie konsoli oraz dodatkowo wypisywać aktualne współrzędne wszystkich jej wierzchołków wyliczone na podstawie wartości pól.
  3. Trzecia – powinna wyrażać przekształcenie symetrii środkowej, tj. jako argument powinna przyjmować współrzędne punktu symetrii środkowej na płaszczyźnie, względem którego figura ma zostać przekształcona, a w swoim działaniu powinna przeliczyć wszystkie wartości tych pól, które są odpowiedzialne za położenie tak, aby w rezultacie tego działania przyjęły one wartości określające położenie figury po przekształceniu.

Napisz program, który w funkcji main deklaruje obiekt typu trapez, po czym:

  1. inicjalizuje go wartościami pobranymi od użytkownika, tak aby powstał prawidłowy trapez, korzystając z metody nr 1,
  2. wywołuje na rzecz tego obiektu metodę wypisującą wszystkie pola i współrzędne w oknie konsoli,
  3. prosi użytkownika o podanie współrzędnych punktu symetrii środkowej i wywołuje na rzecz tego obiektu metodę przekształcenia dla zadanego punktu,
  4. ponownie wywołuje na rzecz tego obiektu metodę wypisującą wszystkie pola i współrzędne w oknie konsoli, aby zobaczyć nowe położenie figury,
  5. ponownie wywołuje na rzecz tego obiektu metodę symetrii środkowej z tym samym punktem symetrii co poprzednio,
  6. a na koniec jeszcze raz wywołuje metodę wypisującą wszystkie pola i współrzędne w oknie konsoli, aby sprawdzić, czy figura wróciła na swoje miejsce.

Wykład 7 – slajdy

PO2015w7.pdf

Kod programu demonstrowanego na wykładzie:


#include <cstdio>
using namespace std;

class gabka {
	float woda;
public:
	void nasacz(float ml) {
		woda = ml;
	};
	float wycisnij(void) {
		return woda/=2;
	};
};
int main() {
	float szklanka = 0; // pusta szklanka
	gabka g;            // nowa sucha gąbka
	g.nasacz(100);      // nasączam gąbkę wodą
	for (int i=0; i < 3; i++)
		szklanka += g.wycisnij();

	printf("%fn", szklanka);
	// printf("%fn", g.woda); czy wolno mi tak napisać?
	return 0;
};

Wejściówka na ćwiczenia nr 8

Napisz program, który pobiera nazwę pliku od użytkownika, otwiera plik tekstowy o podanej nazwie w trybie do odczytu, odczytuje z niego liczbę dodatnią całkowitą, po czym zamyka go. Następnie zaczyna sprawdzać zręczność użytkownika: wyświetla na ekranie dowolny napis testowy, po czym oczekuje na wprowadzenie tego napisu przez użytkownika za pomocą klawiatury mierząc czas, jaki jest potrzebny użytkownikowi na wprowadzenie tego napisu. Do pomiaru czasu użyj funkcji time i difftime. Ta czynność pomiaru powtarzana jest tyle razy, ile wynosi liczba odczytana z pierwszego pliku. Rezultat każdego pomiaru czasu zapisywany jest do listy dynamicznej. Dla skończonej serii pomiarów zapisanych w liście obliczana jest średnia wartość. Po zakończeniu testu zręczności program pobiera od użytkownika jeszcze jedną nazwę pliku, otwiera go w trybie do zapisu i zapisuje tam całą zawartość listy dynamicznej oraz – w ostatnim wierszu – obliczoną wartość średnią. Na koniec plik jest zamykany a lista usuwana.

Uwagi:
Zaproponuj własny sposób sprawdzenia, czy plik o podanej nazwie istnieje. Następnie napisz funkcję, która jako argument wywołania przyjmuje nazwę pliku, a zwraca wartość zero, jeżeli pliku nie ma, oraz 1 – jeżeli istnieje. Użyj tej funkcji w swoim programie do sprawdzenia, czy pierwszy plik istnieje, a jeżeli nie (np. kiedy użytkownik zrobi błąd, źle podając nazwę tego pliku), poproś o ponowne podanie nazwy pliku. Użyj tej funkcji do sprawdzenia również, czy drugi plik – do zapisu – istnieje, a jeżeli istnieje, poproś użytkownika o ponowne podanie nazwy pliku do zapisu (chcemy chronić już istniejące pliki przed ich nadpisaniem nowymi danymi).

Do sprawdzania błędów związanych z dostępem do pliku wykorzystaj stałą errno a do generowania komunikatów funkcje strerror i perror. Wszelkie komunikaty o sytuacjach błędnych, jakie wystąpiły w trakcie pracy programu, wysyłaj do standardowego strumienia dla komunikatów o błędach stderr.

Napisz kod programu tak, aby obsłużył również inne sytuacje błędne, tj. np. kiedy pierwszy plik będzie pusty, lub będzie zawierał liczbę ujemną (przyjmij, że inny napis niż liczba całkowita nie może w nim wystąpić).