Programowanie obiektowe C++ Informatyka/Automatyka i ...
Programowanie obiektowe C++ Informatyka/Automatyka i ...
Programowanie obiektowe C++ Informatyka/Automatyka i ...
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Instytut Sterowania i Systemów Informatycznych<br />
Wydział Elektrotechniki, Informatyki i Telekomunikacji<br />
Uniwersytet Zielonogórski<br />
<strong>Programowanie</strong> <strong>obiektowe</strong> <strong>C++</strong><br />
<strong>Informatyka</strong>/<strong>Automatyka</strong> i Robotyka 1<br />
stopień pierwszy – tytuł inżyniera – Semestr II rok I<br />
Zbiór zadań<br />
1 Zadania powtórkowe z iteracji i rekurencji<br />
1. Opracować funkcję do obliczania wartości kombinacji według wzoru:<br />
C k n = V k<br />
n<br />
P k<br />
=<br />
n!<br />
(n − k)! · 1<br />
k! . (1)<br />
2. Opracować krótki program, który za pomocą metody całkowania prostokątów, obliczy<br />
wartość następującej całki, która przybliża wartości liczby π:<br />
∫ 1 1<br />
π = 4 dx. (2)<br />
0 1 + x2 3. Napisać funkcję obliczającą iteracyjnie wartość symbolu Newtona:<br />
( n n!<br />
=<br />
k)<br />
k!(n − k)! . (3)<br />
4. Napisać funkcję obliczającą rekurencyjnie wartość symbolu Newtona:<br />
( { n 1<br />
= ) ( ) gdy k = 0 lub k = n<br />
k)<br />
+<br />
n−1<br />
. (4)<br />
0 < k < n<br />
( n−1<br />
k−1<br />
k<br />
5. Napisać funkcję obliczającą iteracyjnie wartość symbolu Newtona, według wzorów:<br />
( ∏ n ki=1<br />
n − i + 1<br />
k∏ n − i + 1<br />
= ∏<br />
k)<br />
ki=1<br />
=<br />
. (5)<br />
i<br />
i<br />
6. Opracować krótki program, który za pomocą funkcji iteracyjnej oraz rekurencyjnej, narysuje<br />
choinkę o zadanej wysokości n o następujacym kształcie, jeśli n = 3:<br />
+<br />
+++<br />
+++++<br />
1 Zbiór zadań dotyczy kierunku informatyki/automatyki i robotyki w trybie stacjonarnym (studia dzienne)<br />
oraz w trybie niestacjonarnym (studia zaoczne).<br />
i=1
2 „Małe co nieco o wskaźnikach”<br />
1. Napisać deklaracje następujących zmiennych:<br />
(a) wskaźnik do znaku,<br />
(b) referencja do dziesięcioelementowej tablicy liczb całkowitych,<br />
(c) tablica pięciu wskaźników do liczb rzeczywistych,<br />
(d) wskaźnik do stałej całkowitej,<br />
(e) referencja do wskaźnika znaku,<br />
(f) stały wskaźnik do stałej znakowej,<br />
(g) wskaźnik pięcioelementowej tablicy liczb rzeczywistych,<br />
(h) wskaźnik funkcji o parametrze i wartości w postaci referencji do liczb całkowitych.<br />
2. Napisać deklaracje oraz zainicjalizować wskaźniki następujących funkcji:<br />
(a) int fun(char znak,int *wsk_int),<br />
(b) float* fun2(float,float),<br />
(c) funkcja o parametrze typu całkowitego, zwracająca wskaźnik do tablicy znaków<br />
[3][3],<br />
(d) funkcja o parametrach typu int i int*, której rezultatem jest referencja do znaku.<br />
3. Co oznaczają następujące deklaracje?<br />
(a) char (*r)[];,<br />
(b) char *r[10];,<br />
(c) char q(char *);,<br />
(d) char (*q)(char[]);.<br />
4. Wykorzystując notację wskaźnikową opracować funkcje:<br />
(a) strlen() - przekazującą długość napisu,<br />
(b) strcpy() - kopiującą jeden napis na drugi,<br />
(c) strcmp() - porównującą dwa napisy,<br />
(d) strcat() - łączącą dwa napisy przyjmowane jako argumenty w jeden,<br />
(e) strrev() - sprawdzającą czy dany znak występuje w napisie.<br />
5. Narysować struktury powstałe po wykonaniu poniższych ciągów instrukcji:<br />
class elem {<br />
public:<br />
data : integer;<br />
link : *elem;<br />
};
(a) elem *p = new elem; (*p).data=4; (*p).link=NULL;<br />
(b) elem *p = new elem; p->data=7; p->link=p;<br />
(c) elem *q = new elem; (*q).data=2; q->link=NULL;<br />
elem *p = new elem; p->data=1; (*p)->link=q;<br />
(d) elem *p = new elem; p->data=5;<br />
p->link = new elem; *p->link=*p;<br />
6. Napisać program, który odwzoruje w pamięci operacyjnej następujące struktury:<br />
p<br />
(a)<br />
1 5<br />
7<br />
(b)<br />
p 1 5<br />
7<br />
(c)<br />
NULL<br />
p 0 2<br />
„A”<br />
3 Wstęp do klas<br />
1. Zdefiniowano następujący zalążek klasy, reprezentujący punkt 2D:<br />
class Punkt2D {<br />
private:<br />
float x,y;<br />
public:<br />
char symbol;<br />
...<br />
};<br />
Zadeklarować oraz zdefiniować:<br />
• funkcję składową, która wyświetli symbol punktu oraz jego współrzędne na ekranie<br />
(funkcja ma mieć charakter inline),<br />
• funkcję składową inicjującą współrzędne wartościami losowymi,<br />
• konstruktor inicjujący,<br />
• funkcję składową, która znajdzie współrzędne odbicia symetrycznego punktu względem<br />
środka symetrii, który jest dany jako argument funkcji i wyświetli je na ekranie,
• funkcję składową, która doda współrzędne dwóch punktów i zwróci je jako punkt<br />
wynikowy.<br />
Zdefiniować obiekty i podać przykładowe wywołania metod. Jaka będzie różnica jeśli typ<br />
obiektu zadeklarowany zostanie jako struktura, a nie klasa?<br />
2. Zaprojektować klasę punktNd będącą uogólnieniem klasy z ćwiczenia (1) na punkty n-<br />
wymiarowe (współrzędne przechowywane powinny być w dynamicznie rezerwowanej tablicy).<br />
Zadeklarować oraz zdefiniować:<br />
(a) konstruktor inicjujący,<br />
(b) uzupełnić definicję klasy o składnik statyczny, który ma za zadanie przechowywać<br />
liczbę istniejących obiektów klasy, a następnie dokonać jego inicjalizacju,<br />
(c) funkcję składową o nazwie dodaj, realizującą dodawanie dwóch punktów,<br />
(d) funkcję globalną o nazwie dodaj, realizującą dodawanie dwóch punktów,<br />
(e) destruktor uwzględniający zwalnianie dynamicznie przydzielonej pamięci.<br />
3. Zadeklarować unię mogącą przechowywaæ elementy typu float, int i char, a następnie:<br />
(a) napisać krótki program, w którym należy zainicjalizować unię oraz zrealizowaæ operacje<br />
przypisania jej wartości różnych typów,<br />
(b) napisać funkcję składową wyświetlającą zawartość struktury,<br />
(c) rozbudować unię o pole bitowe w wielkości 2 bitów i zrealizować przypisanie wartości<br />
inicjalizującej,<br />
(d) zadeklarować unię jako anonimową, oraz zrealizować operacje z punktu (a).<br />
4. Dane są następujące definicje:<br />
class X {<br />
int i;<br />
float j;<br />
public:<br />
int fun(int i,float j){return i;};<br />
};<br />
int fun(int i, float j){return i;};<br />
X A;int i;float j;<br />
Ocenić poprawność poniższych instrukcji:<br />
• int fun(int i,int j){return i;};<br />
• int fun(int i,float j){return i;};<br />
• int fun(float j,int i){return i;};<br />
• void fun(int i,float j){};<br />
• int fun(int i,float j);
• int fun(int i,float j,float k=0){return i;};<br />
• A.fun(i,j);<br />
• A.X::fun(i,j);<br />
• ::fun(i,j);<br />
5. Skonstruować klasę wektor do przechowywania współrzędnych trójwymiarowych punktu<br />
przestrzennego, a następnie napisać funkcje składowe realizujące podstawowe działania<br />
na wektorach (suma, różnica, iloczyn skalarny, iloczyn wektorowy). Ponadto wyposażyć<br />
klasę w funkcje służące do pobierania wektora z klawiatury, generowania losowego współrzędnych<br />
oraz wyświetlania wartości na ekranie.<br />
6. Dana jest klasa o następującym szkielecie:<br />
class PascalString {<br />
char t[256];<br />
public:<br />
//... definicje konstruktorów<br />
//... pozostała część interfejsu<br />
};<br />
Zakłada się, że element zerowy łańcucha przeznaczony jest na przechowanie jego długości.<br />
Zadeklarować i zdefiniować:<br />
• definicję konstruktora: standardowego i domniemanego,<br />
• funkcje interfejsu: zwracającą długość łańcucha, wycinającą jego wybrany fragment<br />
i składajacą dwa łancuchy w jeden.<br />
7. Rozważyć następujące definicje:<br />
class nr_tel{<br />
char nr_tel[20];<br />
char nazwisko[20];<br />
char imie[12]; ...<br />
};<br />
class ksiazka_tel {<br />
static int licznik;<br />
nr_tel numery[50]; ...<br />
};<br />
Dodać niezbędne funkcje dotyczące obsługi książki telefonicznej (dodawanie nowych i<br />
usuwanie istniejących numerów, wyszukiwanie po nazwisku). Jak również klasa powinna<br />
posiadać składnik statyczny, którego zadaniem będzie sprawdzanie wolnego miejsca w<br />
książce.<br />
8. Dla następujących struktur:
union element { char a; int b; float c; };<br />
class zbior { element *wsk_liczba; ... };<br />
rozbudować klasę zbiór o metody wykonujące podstawowe operacje na zbiorach (∪, ∩, \,<br />
∈) których elementami mogą być zmienne znakowe, całkowite lub rzeczywiste.<br />
9. Napisać definicję klasy "krzywa" zawierającą dynamiczną tablicę punktów (zastosować<br />
klasę punkt z ćwiczenia (1)) na płaszczyźnie, które tworzą krzywą łamaną. Klasa ma<br />
posiadać metody dotyczące generowania krzywych losowo, wyświetlania w trybie graficznym,<br />
realizacją skalowania oraz translacji o zadany wektor, dodawania i usuwania<br />
punktów krzywej.<br />
10. Opracować klasę „Liczba”, która będzie przechowywać liczbę całkowitą, klasa będzie także<br />
zawierać informację, o dziedzinie liczby. Klasa „Liczba” powinna posiadać metody do<br />
realizacji podstawowych operacji arytmetycznych.<br />
11. Niech będzie dany typ złożony reprezentujący liczbę zespoloną:<br />
class fLiczbaZespolona {<br />
private:<br />
float Re,Im;<br />
public:<br />
// uzupełnić we własnym<br />
// zakresie ;-)<br />
};<br />
Zadeklarować i zdefiniować:<br />
(a) konstruktor inicjalizujący (zastosować listę inicjalizacyjną),<br />
(b) konstruktor domniemany,<br />
(c) metodę dodaj umożliwiającą dodanie dwóch liczb zespolonych,<br />
(d) funkcję operatorową „+” wykonującą zadanie z punktu (11c) w wersji globalnej oraz<br />
jako składową klasy,<br />
(e) funkcję operatorową „+” wykonującą dodawanie wartości rzeczywistej do liczby zespolonej,<br />
tak aby możliwa była notacja przemienna (a dokładniej: float + fLiczbaZespolona<br />
oraz fLiczbaZespolona + float), zdefiniować obiekty i napisać przykładowe<br />
wywołania funkcji.<br />
12. Dany jest przykład klasy:<br />
class wizytowka {<br />
public:<br />
char *nazw; char *imie; char *tel;<br />
};<br />
Zadeklarować i zdefiniować:
(a) konstruktor inicjalizujący (domniemany),<br />
(b) konstruktor kopiujący,<br />
(c) operator przypisania „=” umożliwiający skopiowanie zawartości obiektu,<br />
(d) destruktor.<br />
Zdefiniować obiekty i napisać przykładowe wywołania funkcji.<br />
13. Dla następującej struktury:<br />
class Macierz2D {<br />
static int pamiec;<br />
int (*T)[n][m];<br />
};<br />
Zrealizować następujące ćwiczenia:<br />
(a) zdefiniować konstruktor domniemany,<br />
(b) przeładować operator „-” w wersji jednoargumentowej oraz dwuargumentowej,<br />
(c) przeładować operator preinkrementacji oraz postinkrementacji,<br />
(d) przeładować operatory new i delete, tak aby prowadzić statystykę zużywanej pamięci.<br />
14. Przeanalizować poniższy fragment kodu<br />
#include<br />
class samochod {<br />
int filtr_powietrza;<br />
public:<br />
int akumulator, zbiornik_paliwa;<br />
//...<br />
};<br />
samochod A,B;<br />
int *wsk1;<br />
int samochod::*wsk2=&samochod::akumulator;<br />
void main() {<br />
wsk1 = &(A.akumulator);<br />
cout
(b) wsk1=&(B.filtr_powietrza);<br />
(c) wsk2=samochod::filtr_powietrza;<br />
(d) wsk2++;<br />
(e) wsk1++;<br />
15. Określić poprawność następujących deklaracji, podać również przyczyny dla których są<br />
poprawne bądź nie?<br />
(a) f(int i,int j,int k=0); f(int i,int j);<br />
(b) f(int i,char j); f(int j);<br />
(c) f(const int k); f(int k);<br />
(d) f(const int &k); f(int &k);<br />
16. Określony został zalążek następującej klasy wektor zdefiniowanej jako<br />
class wektor{<br />
int x,y,z;<br />
public:<br />
// ... pozostały interfejs<br />
};<br />
Dodać implementację następujących elementów:<br />
(a) konstruktor domniemany,<br />
(b) konstruktor inicjujący z listą inicjalizacyjną,<br />
(c) składowe funkcje operatorowe „+”, „-”, „*” umożliwiające dodawanie, odejmowanie i<br />
mnożenie wektorów,<br />
(d) funkcje z punktu (c) w wersji globalnej.<br />
17. Dla klasy string:<br />
class mystring {<br />
int roz;<br />
char *wsk;<br />
public:<br />
//...metody<br />
};<br />
Dokonać implementacji:<br />
(a) następujących konstruktorów: standardowy (z listą inicjalizacyjną), domniemany i<br />
kopiujący,<br />
(b) metody: zwracające rozmiar łańcucha, sklejające dwa łańcuchy w jeden, odwracające<br />
kolejność liter w łańcuchu i porównującą zawartość dwóch łańcuchów,
(c) destruktor,<br />
(d) funkcje operatorowe „«”, „»” oraz „=”.<br />
Czy poniższe definicje konstruktorów są poprawne? Odpowiedź uzasadnić.<br />
(a) string::string(char t[]) :<br />
wsk(new char[roz+1]),<br />
roz(strlen(t))<br />
{<br />
strcpy(wsk,t);<br />
}<br />
(b) string::string(string);<br />
18. Niech będzie dana klasa macierz zdefiniowana nastąpująco :<br />
class macierz{<br />
int liczba_wierszy, liczba_kolumn;<br />
public:<br />
float *tablica;<br />
...<br />
};<br />
Zdefiniować:<br />
(a) konstruktory inicjujący (domniemany) i kopiujący,<br />
(b) składowe funkcje operatorowe „+”, „-”, „*”, umożliwiające dodawanie, odejmowanie i<br />
mnożenie macierzy,<br />
(c) funkcje „+”, „-”, „*” realizujące przemienne dodawanie, odejmowanie i mnożenie macierzy<br />
przez skalar,<br />
(d) operator przypisania „=” umożliwiający skopiowanie macierzy,<br />
(e) funkcję składową obliczającą wyznacznik macierzy kwadratowej,<br />
(f) destruktor.<br />
19. Stosując wskaźniki do składowych klasy posortować 50 elementową wygenerowaną losowo<br />
tablicę obiektów z ćwiczenia (12) według zadanego pola (do porównania łańcuchów<br />
znaków można zastosować funkcję strcmp z pakietu string.h).<br />
20. Zaprojektować specjalny wskażnik do wartości typu całkowitego, który będzie zapamiętywać<br />
10 ostatnio wskazywanych przez niego adresów oraz 20 adresów ostatnio utworzonych<br />
egzemplarzy takiego wskażnika. Następnie przeładować operatory inkrementacji i dekrementacji<br />
dla tej klasy obiektów.
4 Podstawy techniki dziedziczenia<br />
1. Podać deklaracje klasy podstawowej oraz klas pochodnych (przeanalizować również, czy<br />
poszczególne nazwy klas są odpowiednie, czy istnieje możliwość ich zmiany na bardziej<br />
adekwatne), tak aby odzwierciedlały poniższy digraf relacji pomiędzy klasami:<br />
Każda z klas ma posiadać zadeklarowaną funkcję wyświetlającą figurę o nazwie rysuj().<br />
Zdefiniować obiekty i napisać przykładowe wywołania z zastosowaniem funkcji rysuj().<br />
2. Zadeklarować klasę podstawową oraz klasy pochodne, tak aby odzwierciedlały następujący<br />
digraf relacji pomiędzy klasami:<br />
Zrealizować ćwiczenie bez oraz ze uwzględnieniem klas wirtualnych. Zdefiniować obiekty i<br />
napisać przykładowe wywołania funkcji. Jaki jest dostęp do pól klas podstawowych bądź<br />
poprzednich w klasach pochodnych?<br />
3. Dane są klasy:<br />
class A { private: int a;};<br />
class B { protected: int b;};<br />
class C { public: int c;};<br />
class D : protected A, public B {};<br />
class E : public D, protected C {public: A::c;};<br />
class F : private E, public A {};<br />
Zrealizować następujące ćwiczenia:<br />
(a) odtworzyć diagram dziedziczenia,<br />
(b) określić kolejność wywoływania konstruktorów dla każdej z klas,<br />
(c) określić rodzaj dostępu do zmiennych a, b, c w klasach D, E oraz F .<br />
4. Dane są szkielety klas:
class motocykl { /*...*/ } M, *wsk_M;<br />
class Honda: public motocykl {<br />
/*...*/} H, *wsk_H;<br />
class Ducati: public motocykl {<br />
/*...*/} D, *wsk_D;<br />
class Składak: public Honda, public Ducati {<br />
/*...*/} S, *wsk_S;<br />
Wskazać które z poniższych zestawów instrukcji są błędne, a które poprawne odpowiedź<br />
uzasadnić?<br />
(a) M=H;wsk_H=wsk_M;<br />
(b) D=M;wsk_D=wsk_M;<br />
(c) M=H;wsk_M=wsk_H;<br />
(d) H=S;wsk_M=wsk_S;<br />
(e) D=H;wsk_H=wsk_S;<br />
(f) M=S;wsk_S=&D;<br />
5. Dana jest klasa:<br />
class fLiczbaZespolona {<br />
private:<br />
float Re,Im;<br />
public:<br />
// uzupełnić we własnym<br />
// zakresie ;-)<br />
};<br />
oraz funkcja operatorowa:<br />
fLiczbaZespolona operator+( fLiczbaZespolona, fLiczbaZespolona);<br />
Zdefiniować konstruktor konwertujący tak, by poprawne były wyrażenia:<br />
licz_zesp z1,z2;<br />
float a=2.5;<br />
z1=z2+a; z2=a+z1;<br />
6. Uzupełnić klasę string:<br />
class string<br />
int roz;<br />
char *wsk;<br />
public:<br />
// ...metody<br />
};
o funkcję operatorową:<br />
ostream& operator
Dodatkowo obiekt każdej klasy zawiera w sobie po jednym obiekcie klas, od których<br />
bezpośrednio dziedziczy. Przykładowo, obiekt klasy E, dla której klasami podstawowymi<br />
są A, B oraz C, posiada jako komponenty po jednym elemencie typu A, B i C. Dla<br />
każdej z klas zdefiniować konstruktor i destruktor, a następnie w programie głównym<br />
przetestować kolejność ich wywoływania dla obiektu każdego z zadeklarowanych typów.<br />
10. Niech będzie dany następujący typ danych:<br />
class Tablica1D {<br />
protected:<br />
int rozmiar1;<br />
int *tab;<br />
};<br />
reprezentujący dynamiczną tablicę jednowymiarową. Do klasy dodać następujące elementy:<br />
(a) domniemany konstruktor inicjalizujący, destruktor, operator przypisania, oraz metody:<br />
wyprowadzającą zawartość tablicy na ekran, wyznaczającą wartości minimalną0<br />
i maksymalną, sortującą tablicę,<br />
(b) wykorzystać powyższą klasę i stosując mechanizm dziedziczenia napisać definicję<br />
klasy Tablica2D, która będzie posiadała takie same metody operujące na tablicy<br />
dwuwymiarowej, przy czym sortowanie oraz szukanie minimum i maksimum będzie<br />
realizowane dla każdego wiersza osobno, a wynik w przypadku wartości minimalnych<br />
oraz maksymalnych zwróci jako tablicę wartości,<br />
(c) wykorzystując klasę Tablica1D oraz Tablica2D zrobić to samo co w punkcie (b),<br />
tylko dla tablicy trójwymiarowej (sortowanie i szukanie min/max zrealizować w odniesieniu<br />
do pierwszego wymiaru tablicy).<br />
11. Zdefiniować klasę bazową Subject zawierającą trzy funkcje f(), g() i h(). Następnie z<br />
klasy tej wyprowadzić klasy Implementation1, Implementation2 oraz Proxy. Ta ostatnia<br />
powinna zawierać wskaźnik do obiektu typu Subject, a wszystkie jej metody powinny<br />
zwracać i być wywoływane na rzecz wskaźnika takiego właśnie typu obiektu. Konstruktor<br />
klasy Proxy powinien inicjalizować wskaźnik do typu Subject zainstalowanego w jej<br />
wnętrzu. W programie głównym zdefiniować dwa różne obiekty Proxy, posiadające inną<br />
implementację. Następnie zmodyfikować klasę Proxy w sposób umożliwiający dynamiczną<br />
zmianę implementacji tej klasy.
5 Polimorfizm oraz funkcje wirtualne<br />
1. Dla schematu dziedziczenia A → B → C:<br />
(a) zdefiniować klasy przy założeniu, że klasa A ma być klasą abstrakcyjną,<br />
(b) wyposażyć wszystkie klasy w wirtualną metodę nazwa zwracającą nazwę klasy,<br />
(c) dodać destruktory wirtualne,<br />
(d) dodać funkcję globalną zaprzyjaźnioną z klasą A, tak aby mogła wykonać to samo<br />
co funkcje z podpunktu (b).<br />
2. Napisać definicję klasy z trzema przeładowanymi funkcjami wirtualnymi. Stworzyć nową<br />
klasę dziedzicząca po pierwszej, z tylko jedną przeładowaną funkcją wirtualną. Utworzyć<br />
obiekt klasy pochodnej i odpowiedzieć na następujące pytania:<br />
(a) Czy można wywołać wszystkie trzy bazowe funkcje poprzez obiekt klasy pochodnej<br />
i ewentualnie w jaki sposób?<br />
(b) Czy po zrzutowaniu adresu klasy pochodnej na adres klasy bazowej można wywołać<br />
wszystkie funkcje?<br />
(c) Czy po usunięciu definicji funkcji w klasie pochodnej można wykonać podpunkt (a)?<br />
3. Poprawić błędy w programie, a następnie przeanalizować jego działanie.<br />
#include |<br />
| void main() {<br />
using namespace std; | X ob1;Y ob2; Z ob3;<br />
| ob2.fun1; ob2.fun2;<br />
class X { |<br />
public: | X *wsk = &ob2;<br />
static int x1; | wsk->fun1(); wsk->fun2();<br />
void virtual fun1() | wsk->X::fun1(); wsk->X::fun2();<br />
{ coutfun2();<br />
| wsk->X::fun1(); wsk->Z::fun2();<br />
class Y: public X { | }<br />
public: |<br />
void virtual fun1() |<br />
{ cout
Każda z klas powinna posiadać funkcje wirtualne rysuj(), przesun() oraz obrot().<br />
Dokonać wirtualnego wywołania tych funkcji dla różnego typu obiektów.<br />
6. Napisać klasę zawierającą dwie metody wykonujące to samo zadanie, jedną w wersji<br />
wirtualnej, a drugą niewirtualnej. Dodać nową klasę dziedziczącą ze wspomnianej klasy,<br />
a następnie porównać czasy wywołania każdej z funkcji (posłużyć się np. funkcją clock()<br />
— plik nagłówkowy time.h).<br />
7. Napisać krótki program obrazujący róźnicę pomiędzy wywołaniem funkcji wirtualnej wewnątrz<br />
normalnej funkcji składowej klasy, a wywołaniem funkcji wirtualnej wewnątrz<br />
konstruktora. Program powinien pokazać, że takie dwa wywołania generują róźne wyniki.<br />
8. Dane są klasy bazowe rezystor, kondensator i cewka. Wyprowadzić z nich klasy pochodne:<br />
cewka rzeczywista i kondensator rzeczywisty, a z nich z kolei układ RLC. Mając do dyspozycji<br />
tak przygotowany zestaw elementów prostych, zdefiniować układ_rez zawierający<br />
dynamiczną tablicę wskaźników do takich obiektów. Wyznaczyć charakterystykę rezonansową<br />
w zadanym przedziale częstotliwości dla szeregowego i równoległego połączenia<br />
elementów.<br />
6 Formatowanie strumieni<br />
1. Dana jest następująca definicja klasy:<br />
class X { int a[2]; };<br />
Przeładować operatory aby możliwe się stało wczytywanie i wysyłanie do standardowego<br />
strumienia obiektów klasy X.<br />
2. Napisać manipulatory dla klasy iostream:<br />
(a) bezargumentowy mający za zadanie dorzucenie przed wyświetlaną zmienną napisu<br />
„zmienna :”,<br />
(b) jednoargumentowy lin(n), który ma za zadanie przejść n razy do nowej linii.<br />
3. Otworzyć strumień wejściowy dla pliku i przepisać go do strumienia wyjściowego skojarzonego<br />
z innym plikiem.<br />
4. Dla przykładowych strumieni:<br />
ifstream in; ofstream out;<br />
(a) powiązać strumień wejściowy z wyjściowym, tak aby każda zmiana w strumieniu<br />
wejściowym odzwierciedlona była w strumieniu wyjściowym,<br />
(b) zlikwidować wiżzanie pomiędzy standardowymi strumieniami wejściowym i wyjściowym,<br />
(c) przemianować standardowe strumienie wejścia i wyjścia tak, aby dane z cin płynęły<br />
do out, a dane z in płynęły do cout.
5. Otworzyć plik poprzez utworzenie obiektu typu ifstream o nazwie in. Następnie utworzyć<br />
obiekt os typu ostrstream i przekopiować do niego całą zawartość otwartego pliku (użyć<br />
metodę rdbuf). Zamienić wszystkie litery w os na duże i zachować wynik w nowym pliku,<br />
po czym zwolniæ pamięć zajętą przez ten strumieñ.<br />
6. Napisać program, który dopisze na początku i na końcu wszystkich plików żródłowych z<br />
rozszerzeniem *.h komentarz dotyczący praw autorskich.<br />
7. Otworzyć plik o nazwie podanej jako argument programu. Następnie wyświetlić wszystkie<br />
jego linie zawierające jedno ze słów podanych jako następne argumenty wraz z numerami<br />
wierszy odpowiadającymi im w pliku.<br />
8. Dodać nowe manipulatory dla standardowego strumienia wyjściowego:<br />
(a) bin(x) wyświetlający liczbę całkowitą x w systemie binarnym,<br />
(b) bin2(x) wyświetlający liczbę zmiennoprzecinkową x w systemie binarnym,<br />
(c) convert(x, n) wyświetlający liczbę całkowitą x w systemie o podstawie n,<br />
(d) convert2(x, n) wyświetlający dziesiętnie liczbę całkowitą x podaną w systemie o<br />
podstawie n.<br />
9. W oparciu o strumienie napisać program, który podzieli plik o dużych rozmiarach na<br />
zestaw mniejszych plików. Następnie opracować program, odwracający ten proces tzn.<br />
skleić z powrotem pliki w jeden wynikowy.<br />
7 Szablony<br />
1. Opracować szablon funkcji do wyznaczania iloczynu dwóch argumentów:<br />
(a) zrealizować funkcję szablonową w wersji normalnej i operatorowej,<br />
(b) dodać funkcję wyspecjalizowaną dla tablic jednowymiarowych reprezentujących wektory<br />
(np.: 3,4,5,... elementowe),<br />
(c) wprowadzić domniemany parametr szablonu określający rozmiar tablicy.<br />
2. Przeanalizować poniższe deklaracje:<br />
int i1;<br />
const int i2;<br />
float f1,f2;<br />
template int fun(T, T*);<br />
template U fun (T, T*,U);<br />
int fun(int, int*);<br />
int fun(double, double*,double=0.0);<br />
Rozstrzygnąć, która z funkcji zostanie wywołana, gdy w programie pojawia się polecenie:<br />
(a) i1=fun(i2,&i1);
(b) f1=fun(f2,&f2);<br />
(c) f1=fun(f2,&f2,0.0);<br />
(d) i1=fun(i2,&f2);<br />
3. Zdefiniować szablon klas, przechowujący wskaźnik do pewnego obiektu. Wyposażyć go w<br />
metodę show() wyświetlający wartość tego wskaźnika oraz konstruktor rezerwujący dla<br />
niego pamięć. Pokazać przykładowe deklaracje obiektów wykorzystujących ten szablon.<br />
4. Zrealizować na prostych przykładach dziedziczenie:<br />
(a) klasy szablonowej przez zwykłą klasę,<br />
(b) szablonu klas przez zwyklą klasę,<br />
(c) klasy szablonowej przez szablon klas,<br />
(d) szablonu przez inny szablon,<br />
(e) zwykłej klasy przez specjalizowaną klasę szablonową,<br />
(f) klasy szablonowej przez inną klasę szablonową.<br />
5. Stworzyć szablon funkcji fibonacci() umożliwiający wyznaczanie kolejnych elementów ciągu<br />
Fibonacciego dla różnego typu argumentów (np.: long, float etc.).<br />
6. Stworzyć szablon funkcji sortującej tablicę liczb. Dodać możliwość sortowania także tablic<br />
łańcuchów.<br />
7. Opierając się na szablonie klasy z zadania 2 wyposażonej dodatkowo w funkcje liczenia<br />
sumy oraz sumy kwadratów elementów, wyprowadzić dwuwymiarową tablicę liczb dowolnego<br />
typu z przeładowanymi metodami z klasy bazowej. Sprawdzić działanie polimorfizmu<br />
dla tych klas.<br />
8. Zaprojektować szablon klasy przechowującej dane w postaci listy, z metodami dotyczącymi<br />
dodawania oraz usuwania elementu, przeładowanym operatorem [] pozwalającym<br />
na pracę z listą tak jak z tablicą i wyświetlaniem zawartości. Ponadto zrealizować metodę<br />
znajdującą adres ostatniego elementu na liście w taki sposób, by mogła pracować z<br />
dowolnym typem przez nią zwracanym.<br />
8 Wyjątki<br />
1. Stworzyć klasę z odpowiednią funkcją składową, zgłaszającej wyjątk. Utworzyć także klasę<br />
celem wykorzystania jej jako obiektu wyjątku. Ma ona zawierać pojedynczy wskaźnik<br />
char* reprezentujący komunikat opisujący wyjątek. Wyposażyć ją w inicjalizujący konstruktor<br />
domniemany, uzupełniający treść komunikatu. Napisać blok obsługujący wyjątek<br />
poprzez wyprowadzenie na ekran treści komunikatu.<br />
2. Przeanalizować poniższy fragment programu i wyjaśnić jaka będzie wartość zmiennej i w<br />
przypadku, gdy obiekt E, jest typu:
(a) const int E,<br />
(b) int *E,<br />
(c) int &E,<br />
(d) float E,<br />
(e) int *&E,<br />
(f) const float & const E<br />
//...<br />
int i=1;<br />
try{<br />
try{<br />
throw E;}<br />
catch(int &){i++;throw;}<br />
catch(const int){i+=2;}<br />
catch(float *){i-=2;}<br />
catch(int *){i--;throw;}}<br />
catch(int *){i*=2;}<br />
catch(int){i--;}<br />
catch(...){i--;}<br />
//...<br />
3. Dany jest następujący schemat dziedziczenia klas: A → B → C. W każdej z nich znajdują<br />
się wirtualne metody nazwa wyświetlające nazwę typu obiektu na rzecz którego są<br />
wywoływane. Opisać efekt działania następujących operacji:<br />
(a) try {C ob1;throw ob1;} catch(B ex1) {ex1.nazwa();}<br />
(b) try {C ob2;throw ob2;} catch(B &ex2) {ex2.nazwa();}<br />
(c) try {static C ob3;throw &ob3;} catch(A *ex3)<br />
{ex3->nazwa();}<br />
4. Utworzyć klasę z własnym operatorem new. Operator ten ma przydzielić pamięć dla<br />
wybranej losowo liczby obiektów (z przedziału od 5 do 50), a następnie zasymulować ”bląd<br />
wyczerpania pamięci” i zasygnalizować sytuację wyjątkową. Dodać statyczną metodę,<br />
która odzyska przydzieloną pamięć. Następnie utworzyć blok instrukcji programu odporny<br />
na wystąpienie tego typu wyjątku.<br />
5. Utworzyć destruktor zgłaszający wyjątęk a następnie opracować program udowadniający,<br />
że takie rozwiązanie może prowadzić do niekontrolowanego zakończenia programu przez<br />
funkcję terminate(). Wykorzystać funkcję set terminate() do prawidłowego zamknięcia<br />
programu. Następnie wykazać to samo w przypadku konstruktora kopiującego.<br />
6. Prześledzić proces zgłaszania i obsługi wyjątku przy użyciu własnej klasy z konstruktorami<br />
inicjującym oraz kopiującym dostarczającymi możliwie wyczerpujących informacji<br />
o tym jak obiekt został utworzony. Pokazać, że obiekty zgłoszonych wyjatków są odpowiednio<br />
likwidowane, natomiast gdy rzucany jest wskaźnik do obiektu dynamicznego to<br />
nie jest zwalniana przypisana mu pamięć. Zaproponować rozwiązanie tego problemu.