1. Operatory których nie da sie przeładować:
-'sizeof'
- .
- .*
- ?:
- ::
-'<static_cast>, <dynamic_cast>,<const_cast>,<reinterpret_cast>'
2.Operatory rzutowania:
- <static cast>, <dynamic cast>,<const cast>,<reinterpret cast>,
3.Czega się nie dziedziczy:
-konstruktorów,
-dekonstruktor,
-operatory przypisania,
4.Polimorfizm: mechanizmy pozwalające programiście używać wartości, zmiennych i podprogramów na kilka różnych sposobów. Inaczej mówiąc jest to możliwość wyabstrahowania wyrażeń od konkretnych typów
Konstruktor -- specjalna funkcja składowa klasy.
class klasa {
klasa (opcjonalne lista argumentów formalnych);
} Własności konstruktora:
- ma tę samą nazwę jak klasa,
- może nadawać składnikom obiektu wartości,
- może być przeładowany,
- nie ma typu zwracanej wartości !!!
- może tworzyć obiekty kwalifikowane przez const albo volatile ale sam nie może być takich typów,
- nie może być typu static – musi działać na składowych niestatycznych (wskaźnik this),
- nie może być typu virtual, zapamiętaj
- jeśli obiekt ma być składnikiem unii, to jego klasa nie może mieć żadnego konstruktora.
Konstruktor jest wywoływany przy: tworzeniu obiektów chwilowych, konstrukcji obiektów złożonych.
Dodatkowo
konstruktor klasy podstawowej jest wywoływany przy tworzeniu obiektu klasy pochodnej
Agregat – skupisko danych – jest tablica obiektów klasy K lub obiekt klasy K gdy klasa K:
nie ma składników danych prywatnych lub zastrzeżonych (private, protected),
nie ma konstruktorów,
nie ma klas podstawowych,
nie ma funkcji wirtualnych.
Konwersja – dopasowanie typów, może być jawne albo niejawne
Konwersja automatyczne gdy: następuje przypisanie wartości jednego typu arytmetycznego zmiennej innego typu arytmetycznego, w wyrażeniu użyto różnych typów, wartości są przekazywane do/z funkcji.
Potencjalne problemy przy konwersji:
a) typu większego Utrata dokładności
na mniejszy wartość może być poza
zakresem
b) typu zm.przecin. Utrata części ułamkowej
na stałoprzecinkowej wartość początkowa może być poza zakresem –
wartość niezdefiniowana
c) większego na mniejszy wartość może być poza
typ całkowity zakresem – kopia młodszych
bajtów
Dla czterech operatorów ich przeładowanie musi być zrealizowane jako niestatyczna metoda klasy. Są to:
–operator przypisania: „=”,
–operator odwołania do elementu tablicy: „[ ]”,
–operator wywołania funkcji: „( )”,
–operator odwołania do składowej udostępnionej przez wskaźnik: „->”.
Klasę pochodną można wykorzystać do definiowania dodatkowych:
a) danych składowych,
b) funkcji składowych,
c) zdefiniować składnik istniejący w klasie podstawowej.
Klasa podstawowa bezpośrednia to ta, która znajduje się na liście pochodzenia danej klasy.
Klasa podstawowa pośrednia to ta, która znajduje się na liście pochodzenia jednej z klas podstawowych dla danej klasy.
W informatyce: klasa pochodna nie musi mieć tylko jednej bezpośredniej klasy podstawowej, może dziedziczyć z wielu.
Taka sytuacja to dziedziczenie wielokrotne:
jeśli lista pochodzenia zawiera więcej niż jedną klasę
class K : public L, public M { ... };
Klasy podstawowe muszą być wcześniej zdefiniowane !!!
Dostęp jest regulowany podobnie jak w przypadku jednej klasy podstawowej.
static_cast – dla dobrze i względnie dobrze zachowujących się zmiennych: typowe konwersje bez operatora rzutowania, utrata informacji, wymuszona konwersja z void*, niejawne, statyczna nawigacja w klasach
const_cast - rzutowanie z typów const do nie-const i odpowiednio z volatile do nie-volatile:
reinterpret_cast – zakłada, ze obiekt jest obrazem bitowym, który może być traktowany jako obiekt innego typu.
dynamic_cast – bezpieczne rzutowanie w „dół” w przypadku dziedziczenia.
Rozpoznawanie typu obiektu mechanizm RTTI (RunTime Type Identification):
pozwala na rozpoznanie typu obiektu w czasie wykonywania programu – wewnątrz wywołanej funkcji pozwala na rozpoznanie typów argumentów.
Użyj klasy type_info (typeinfo.h) o składowych:
funkcje name, operator==, operator!=
- jeśli chcesz rozpoznać obiekty klasy podstawowej i pochodnych to klasa podstawowa powinna zawierać przynajmniej jedną funkcję wirtualną,
- ze względu na przeładowanie operatorów == i != możliwe są porównania typów. Typeid(zmienna, wsk).name()
Polimorfizm (wielość postaci) – mechanizm umożliwiający różne zachowanie się kodu w zależności od typu obiektu, na który działa Wspomaga dalsze oddzielenie interface od implementacji - separując co od jak
Pozwala na tworzenie rozszerzalnych programów
Wspomaga lepszą organizację i czytelność kodu
Wywołanie przez nazwę lib adres(wskaźnik lub referencja)
5.Zabronione parametry szablonu klas:
-stała dosłowna będąca łańcuchem znaków,
-adres elementów tablicy,
-adres niestatecznego składnika klasy,
-typ (klasy) zdefiniowane lokalnie, np wewnątrz funkcji,
-stała dosłowna w przypadku gdy szablon żąda parametru będącego obiektem.
6.Szablony klas - specjalizacja:
- klasa specjalizowana używa template<> albo nie używa słowa kluczowego template,
- definicja klasy specjalizowanej musi wystąpić po definicje szablonu klas,
- konstruktor klasy specjalizowanej nie jest szablonem funkcji,
- funkcje składowe klasy specjalizowanej nie są definiowane jako szablony funkcji, definicja zewnętrzna musi użyć operatora zasięgu,
7.Szablon klas może wystąpić w liście dziedziczenia jedynie tylko w definicji innego szablonu klas.
8.Zwyczajna lub szablonowa klasa może dziedziczyć tylko i wyłącznie zwykła lub szablonową klasę.
9.Obsługa sytuacji wyjątkowych:
1.mechaniz podobny do if -else if,
2.kolejnosc występowania może decydować o tym który blok zostanie wybrany,
3.kolejnosc bloków może być istotna w przypadku hierarchii dziedziczenia
4. czasem handler wyłapujący wszystko co "leci" : catch(...){}
-powinien występować na końcu zestawu bloków catch- - inaczej przesłoni wszystkie pozostałe.
5.catch(...)
1.nie może ustalić ani typu ani wartości obiektu wyjątku,
2.zwykle wykonuje standartowe czynności: ostrzeżenie, zwalnianie zasobów,
3.może odrzucać wyjątek do ponownego rozpatrzenie przez inne handlery - throw.
10.Pojemnik sekwencyjny można zrealizować przez:
-wektor
-listę
-talię
11.Operacjie na pojemniku:
-zapis na i odczyt pliku pojemnika,
-powiększenie pojemnika,
-umieszczanie w pojemniku jeśli jest jeszcze wolne miejsce
-usunięcie obiektu,
-podanie ilości przechowywanych obiektów,
-różnorodne formy prezentacji zawartości pojemnika
12.Pojemnik pośredni to pojemnik przechowujący wskaźnik do obiektów
13.Sekwencyjne - liniowe porządkowanie przechowywanych elementów
14.Adaptery - gdy wymagane są specyficzne własności - modelowanie struktury takich jak kolejki czy stosy
15.Asocjacyne - przechowywane elementy kojarzone są z kluczami co pozwala na efektywne przeszukiwanie
11. Dzielenie liczb zespolonych:
float zmod2() { return (re*re+im*im); }
zespl conjug() { zespl w; w.re = re; w.im = -im; return w; }
zespl operator/(zespl z1, zespl z2) {
zespl w, l, c; float m;
c = z2.conjug();
l = z1*c;
m = z2.zmod2();
w.s_r(l.g_r()/m); w.s_i(l.g_i()/m);
return w;
}
32. // ...::Generator liczb losowych według rozkładu Gaussa::...
double GenerateByGauss(float mean, float std)
{
static const double pi = 3.1415927;
static const double r_max = RAND_MAX;
double wynik = std*sqrt(-2*log((rand()+1)/r_max))*sin(2*pi*rand()/r_max)+mean;
return wynik;
}
if (d->d_type == "I")
{
d->i_meas[i][j]=(int)GenerateByGauss((d->min + d->max)/2, ((d->min - d->max)/2)/1.96);
if ((d->i_meas[i][j]<d->min) || (d->i_meas[i][j]>d->max))
{
d->i_meas[i][j]=(d->max + d->min)/2;
throw(d);
}
d->average+=d->i_meas[i][j];
friend ostream & operator<< (ostream & ob, student & stu)
friend istream& operator>> (istream &ab, student& o)
16. element listy:
class lista{
structure node{
typob* wskO;
node* nasteo;
node():wskO(NULL),nestep(NULL){}
}
public:
node* glowa
node * ogon
node biezac
lista(){glowa=ogon=biezaca=NULL;}
~lista();
......
};
17. wstawianie na poczatek listy:
nowyW->nastep=bieżacy;
glowa=nowyW;
biezacy=nowyW;
18. Idea iteratorów opiera się na tym, by ułatwić i usprawnić pracę na kontenerach. Daje możliwość dotarcia do danego składnika pojemnika bez konieczności znajomości jego struktury. Słusznie używanie iteratora przypomina pracę przy pomocy zwykłych wskaźników
19.Uzycie iteratora:
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
vector<int> tab;
// inicjujemy wektor kolejnymi liczbami naturalnymi
tab.push_back(1);
tab.push_back(2);
tab.push_back(3);
// wyswietlenie skladnikow wektora tab w petli przy pomocy iteratora
vector<int>::iterator it;
for( it=tab.begin(); it!=tab.end(); ++it )
{
cout<< *it <<'\n';
}
return 0;
}
20.Drzewo w c:
struct drzewo {
struct drzewo *lewy_syn;
struct drzewo *prawy_syn;
char *dane;
};
21.Lista c/c++ jednokierunkowa
1.
typedef struct Towar
{ char Nazwa[20];
float Cena;
int Ilosc;
} Element; // definicja typu danych
// przechowywanych w liście
typedef struct Wezel
{ Element dane;
Wezel *nastepny;
} Wezel;
Wezel *Poczatek = NULL:
2.
int DodajNaPoczatek(Wezel *&poczatek, Element dane) m
{
Wezel *tmp; n
tmp = new Wezel; //(Wezel*)malloc(sizeof(Wezel)); o
if (tmp==NULL) p
{ printf(”BRAK PAMIECI !”);
return 1;
}
tmp->dane = dane; q
tmp->nastepny = poczatek; r
poczatek = tmp; s
return 0;
3.
int DodajZaBiazacy(Wezel *biezacy, Element dane) m
{ Wezel *tmp; n
tmp = new Wezel; // (Wezel*)malloc(sizeof(Wezel)); o
if (tmp==NULL) p
{ printf(”BRAK PAMIECI !”);
return 1;
}
tmp->dane = dane; // tu powinno być wpisanie danych q
tmp->nastepny = biezacy->nastepny; r
biezacy->nastepny = tmp; s
return 0;
4.
void UsunPoczatek(Wezel *&poczatek) m
{ Wezel *tmp; n
tmp = poczatek o
poczatek = tmp->nastepny; p
delete tmp; // free(tmp); q
}
5.
void UsunPoczatek(Wezel *&poczatek) m
{ Wezel *tmp; n
tmp = poczatek o
poczatek = tmp->nastepny; p
delete tmp; // free(tmp); q
}
21lista c/c++ dwukierunkowa:
struct ListElement
{
struct ListElement *next, *prev;
int wartosc;
};
// ******* addBegin *******
void addBegin(struct ListElement **head,struct ListElement **tail, int value)
{
struct ListElement *a;
a =(struct ListElement*)malloc(sizeof(struct ListElement));
a->wartosc = value;
if ((*head)==NULL && (*tail)==NULL)
{
*head=a;
*tail=a;
a->next=NULL;
a->prev=NULL;
}
else
{
a->next=*head;
a->prev=NULL;
(*head)->prev=a;
(*head)=a;
}
}
// ******* addEnd *******
void addEnd(struct ListElement **head,struct ListElement **tail, int value)
{
struct ListElement *a;
a =(struct ListElement*)malloc(sizeof(struct ListElement));
a->wartosc = value;
if ((*head)==NULL && (*tail)==NULL)
{
*head=a;
*tail=a;
a->next=NULL;
a->prev=NULL;
}
else
{
a->prev = *tail;
a->next = NULL;
(*tail)->next = a;
(*tail)=a;
}
}
// ******* addMiddle *******
void addMiddle(struct ListElement **head, struct ListElement **tail, int value, int pos)
{
int m;
struct ListElement *a,*b;
a =(struct ListElement*)malloc(sizeof(struct ListElement));
if (pos == 0)
{
addBegin(head,tail,value);
}
else
{
if (ValidatePosition(*head,*tail,&b,pos))
{
if ((b->next)=NULL)
{
addEnd(head,tail,value);
}
else
{
a->prev=b->prev;
a->next=b;
(b->prev)->next=a;
b->prev=a;
a->wartosc=value;
}
}
}