Edytuj stronę Odnośniki Fold/unfold all ODT export Ta strona jest tylko do odczytu. Możesz wyświetlić źródła tej strony ale nie możesz ich zmienić. ====== Funkcje wirtualne, klasy abstrakcyjne ====== * [[https://pl.wikibooks.org/wiki/C%2B%2B/Funkcje_wirtualne|Funkcje wirtualne]] * prawdziwy polimorfizm - dysponując wskaźnikiem lub referencją klasy bazowej możemy uruchomić metodę wirtualną klasy pochodnej * [[https://pl.wikibooks.org/wiki/C%2B%2B/Funkcje_wirtualne#Metody_i_klasy_abstrakcyjne|metody i klasy abstrakcyjne]] * metoda abstrakcyjna to metoda wirtualna, która posiada tylko deklarację w klasie bazowej, musi być zaimplementowana w klasie pochodnej) * klasa abstrakcyjna to klasa, która posiada przynajmniej jedną metodę abstrakcyjną, nie można stworzyć obiektu tego typu, jedynie obiekty klas pochodnych * kwalifikator [[https://pl.wikibooks.org/wiki/C%2B%2B/Funkcje_wirtualne#Nadpisywanie_metod_wirtualnych_-_override_(C++11)|override]] od C%%++%%11 * dynamiczne rzutowanie ''dynamic_cast<Typ>'' **Przykład funkcji wirtualnej** <code C++> class Bazowa { public: virtual void Wirtualna() { /* implementacja w klasie bazowej */ } }; class Pochodna : public Bazowa { public: virtual void Wirtualna() override { /* implementacja w klasie pochodnej */ } }; </code> **Przykład funkcji abstrakcyjnej** <code C++> class KlasaAbstrakcyjna { virtual int Wirtualna() = 0; }; </code> **Przykład rzutowania dynamicznego** <code C++> Bazowa *bazowa = new Bazowa(); Pochodna *pochodna = dynamic_cast<Pochodna*>(bazowa); if(pochodna) { /* tylko gdy pochodna dziedziczy po bazowej */ } </code> ===== Klasa funkcja Gaussa ===== Program rozszerza implementację programu z poprzednich zajęć, którego źródła znajdziesz w zakładce [[pliki|pliki]] lub w repozytorium [[https://github.com/IS-UMK/po_2024_src/tree/master/07_wielomian_dziedziczenie|GitHub]]. **1.** Utwórz klasę **Gauss** - reprezentującą funkcję Gaussa zawierającą: * dwa pola o wartościach rzeczywistych: ''srednia'' i ''odchylenie'' * konstruktor pozwalający zainicjować funkcję Gaussa wartością średnią i odchyleniem * konstruktor domniemany inicjujący funkcję Gaussa ze średnią 0 i odchyleniem 1 * metodę ''ObliczWartosc'' wyznaczającą wartość funkcji w punkcie $x$. Funkcja Gaussa o wartości średniej $\mu$ i odchyleniu $\sigma$ dana jest wzorem $$f(x)=\frac{1}{\sigma \sqrt{2 \pi}} \exp \left(\frac{-(x-\mu)^2}{2 \sigma^2}\right)$$ * zaprzyjaźnioną funkcję przeciążającą operator << wypisujący komunikat do strumienia postaci \\ ''Gauss (srednia=0, odchylenie=1)'' **2.** Utwórz klasę **Funkcja**, która uogólnia pojecie funkcji i będzie stanowiła klasę bazową klasy **Wielomian** i klasy **Gauss**. Jakie cechy (metody, atrybuty) można uogólnić do klasy Funkcja? \\ Klasa **Funkcja** zawiera: * metodę czysto wirtualną ''ObliczWartosc'' * zaprzyjaźnioną funkcję przeciążająca operator ''<<'' **Diagram klas** {{zajecia:po:funkcja_abstrakcja.png?500|}} **3.** Napisz funkcję globalną o nazwie ''calka'', która zwraca przybliżoną wartość całki funkcji oznaczonej na przedziale $[a,b]$. Obliczenia wykonywane są metodą złożonych prostokątów, gdzie sumujemy pola $n$ prostokątów $h\cdot f(x)$w równoodległych punktach na odcinku $[a, b]$ $$ \int_a^b f(x) \approx h \sum_{i=0}^{n-1} f(a+i \cdot h) \qquad \text{gdzie} \qquad h=\frac{b-a}{n} $$ Argumentami funkcji ''calka'' są: * dowolna funkcja, która dziedziczy po klasie ''Funkcja'' * granice przedziału $a$ i $b$ * liczba węzłów $n$ **4.** Napisz program, który wyznaczy całkę funkcji Gaussa na przedziale $[\mu, 3\sigma]$ (wartości $\mu$ i $\sigma$ wybierz dowolnie) oraz całkę funkcji kwadratowej $f(x)=x^2$ na odcinku $[0, 1]$. Liczbę węzłów $n$ użytą do wyznaczenia całki podaje użytkownik na początku działania programu. **Przykład działania programu:** <code> Ile wezlow calkowania? 100 Funkcja: Gauss (srednia=3, odchylenie=5) Przedzial calkowania: [3, 15] Wynik calkowania = 0.496318 Funkcja: f(x) = 1x^2 Przedzial calkowania: [0, 1] Wynik calkowania = 0.32835 </code> ===== Zadanie 7: Figury ===== Zaimplementuj klasy **Figura**, **Kolo**, **Kwadrat** i **Trojkat** oraz odpowiednie metody zgodnie z podanym diagramem: **Diagram klas** {{zajecia:po:figura_abstrakcja.png?500|}} * klasa ''Kolo'' reprezentuje koło okreslone długością promienia. Konstruktory pozwalają zainicjowac promień koła i nazwę figury. Domniemane wartości to promień 1 i nazwa ''"Kolo"'' * klasa ''Kwadrat'' reprezentuje kwadrat okreslony długością boku. Konstruktory pozwalają zainicjowac długość boku kwadratu i nazwę figury. Domniemane wartości to bok o długości 1 i nazwie ''"Kwadrat"'' * klasa ''Trojkat'' reprezentuje trójkąt równoboczny określony długością boku. Konstruktory pozwalają zainicjowac długość boku trójkąta i nazwę figury. Domniemane wartości to bok o długości 1 i nazwie ''"Trojkat"'' * klasa ''Figura'' reprezentuje abstrakcję dowolnej figury. Konstruktory inicjują nazwę, domniemana wartość nazwy to ''"Figura"'' Każda figura dziedzicząca po klasie ''Figura'' implementuje funkcje obliczające pole i obwód danej figury. $$ \begin{array}{lll} P_{\circ}=\pi r^2 \qquad & P_{\square}=a^2 \qquad & P_{\triangle}=\frac{a^2\sqrt{3}}{4} \\ O_{\circ}=2\pi r & O_{\square}=4a & O_{\triangle}=3a \\ \end{array} $$ Dociąż operator przesunięcia bitowego ''<<'' dla figur w taki sposób aby umieszczał w strumieniu wyjściowym ''std::ostream'' napis zawierający nazwę figury, wartość pola oraz obwodu figury, np.: <code C++> Kwadrat k(3); cout << k << endl; Trojkat t(3); cout << t << endl; </code> spowoduje wypisanie na konsoli komunikatu postaci <code> Kwadrat o polu 9 i obwodzie 12 Trojkat o polu 3.89711 i obwodzie 9 </code> Napisz klasę ''Sumator'', której zadaniem jest sumowanie pól powierzchni figur. Klasa posiada pole ''suma'' o wartości rzeczywistej oraz udostępnia następujące operacje: * konstruktor domyślny inicjuje sumator ''suma=0'' * funkcję składową ''Dodaj'', która przyjmuje w argumencie dowolną figurę (obiekt pochodny klasy ''Figura'') i dodaje do pola ''suma'' wartość pola podanej figury * funkcja składowa ''Wynik()'' zwraca aktualną wartość sumy pół figur, które dotychczas zostały dodane metodą ''Dodaj''. Napisz program wykorzystujący klasę ''Sumator'' do policzenia sumy pól ''n'' kół o promieniach $r=1, 2, 3, ..., n$ i $n$ kwadratów o bokach $a=1, 2, 3, ..., n$ oraz $n$ trójkątów równoramiennych o bokach $a=1, 2, 3, ..., n$. Wartość całkowitą $n$ podaje użytkownik na początku działania programu. **Przykład działania programu:** <code> n=3 1: dodaje Kolo o polu 3.1415 i obwodzie 6.283 2: dodaje Kolo o polu 12.566 i obwodzie 12.566 3: dodaje Kolo o polu 28.2735 i obwodzie 18.849 1: dodaje Kwadrat o polu 1 i obwodzie 4 2: dodaje Kwadrat o polu 4 i obwodzie 8 3: dodaje Kwadrat o polu 9 i obwodzie 12 1: dodaje Trojkat o polu 0.433013 i obwodzie 3 2: dodaje Trojkat o polu 1.73205 i obwodzie 6 3: dodaje Trojkat o polu 3.89711 i obwodzie 9 Suma pol wynosi 64.0432 </code> Rozwiązanie w postaci plików nagłówkowych ''*.h'' i źródłowych ''*.cpp'' umieść w Moodle [[https://moodle.umk.pl/mod/assign/view.php?id=209746|Zadanie 7]]