-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #15 from tgpetrica/add_2022-05-19
initial commit
- Loading branch information
Showing
2 changed files
with
161 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
## Mostenire multipla | ||
C++ este unul dintre putinele limbaje de programare care accepta mostenire multipla, adica o clasa mosteneste mai multe clase. Clasele mostenite se enumera separate prin virgula dupa caracterul `:`, specificand in fata fiecarei clase modul in care acea clasa este mostenita: `public`, `protected`, `private` si optional specificatorul `virtual`. | ||
|
||
 | ||
|
||
```cpp | ||
class C: public A, public B | ||
{ | ||
... | ||
C(...):A(...),B(...) | ||
{...} | ||
}; | ||
``` | ||
Inainte de crearea obiectul instanta `C` sunt create subobiectele instanta `A` si apoi celei instanta `B`. | ||
Mostenirea multipla vine si cu probleme suplimentare. Problema cea mai cunoscuta este cea a "Diamantului" care apare atunci cand o clasa mosteneste mai multe clase si cel putin doua din cele mostenite au stramos comuni. La instantiere, facilitatile stramosului ajung in obiectul creat pe doua cai. De fapt, obiectul creat va avea doua subobiecte instanta stramosului. | ||
 | ||
```cpp | ||
class S | ||
{ | ||
public: | ||
void f(){cout << "f" << endl;} | ||
} | ||
class A: virtual public S | ||
{}; | ||
class B: virtual public S | ||
{}; | ||
class C: public A, public B | ||
{}; | ||
void main() | ||
{ | ||
C c; | ||
} | ||
``` | ||
La instantierea clasei `C` o data cu obiectul `c` apar doua obiecte instanta `A`, respectiv `B` si pentru fiecare dintre aceste ultime doua obiecte cate un subobiect `S`, adica in total 5 obiecte in memorie. Problema apare atunci cand din obiectul instanta `C` incercam sa apelam/utilizam o facilitate mostenita din clasa `S`, fie ea camp sau functie, adica, in exemplul nostru, problema apare la apelul `c.f();`. Din cauza ca in memorie exista doua subobiecte instanta `S`, compilatorul nu poate decide din care aceste subobiecte va apela functia `f()`, rezultand eroare la compilare. | ||
Solutia consta in a mosteni clasa `S` virtual. Se spune astfel ca `S` este o **clasa virtuala** in ierarhie. In urma mostenirii virtuale a clasei `S`, la instantierea clasei `C` se va creea un singur subobiect `S` si in consectinta apelul `c.f();` nu mai genereaza eroare la compilare. | ||
|
||
## Clase imbricate | ||
Exista posibilitatea declararii unei clase in interiorul altei clase. | ||
```cpp | ||
class A | ||
{ | ||
... | ||
class B | ||
{...}; | ||
... | ||
}; | ||
``` | ||
In exemplul de mai sus, spunem ca `B` este **imbricata** in clasa `A`. | ||
Clasa `B` nu are acces la membrii protejati sau privati din clasa `A` si nici invers. | ||
O clasa o descriem imbricata in alta clasa in general atunci cand numai in implementarea clasei mari este necesara existenta unor obiecte instanta clasei imbricate. Putem insa instantia clasa imbricata din exterior folosind operatorul de rezolutie: | ||
```cpp | ||
A::B b; | ||
``` | ||
|
||
```cpp | ||
class C | ||
{ | ||
... | ||
class B | ||
{...}; | ||
... | ||
}; | ||
``` | ||
Cele doua clase, desi au acelasi nume, sunt diferite (`B` din `A` si `B` dn `C`). | ||
```cpp | ||
C::B | ||
``` | ||
|
||
## Clase template | ||
Pe langa functii template, C++ ofera ca suport de programare generica si *clase template* pentru care unul sau mai multe tipuri de date sunt generice (nespecificate atunci cand descriem clasa). | ||
Inaintea unei clase template trebuie sa apara acea specificatie pe care am intalnit-o la functiile template si anume, cuvantul rezervat `template`, urmat de o lista de date generice, specificata intre `<` si `>`. In fata fiecarui tip generic, apare tipul rezervat `class`. | ||
|
||
```cpp | ||
template <class T1, class T2,...> | ||
class A | ||
{...}; | ||
``` | ||
Pentru a nu avea probleme la link-editare in Visual C++ trebuie sa implementam toate metodele in momentul descrierii clasei, ci nu separat in fisier `.cpp`. | ||
Daca in cazul functiilor template nu era nevoie la apel sa indicam tipurile de date ce substituie tipurile generice, identificarea lor facandu-se pe baza tipurilor de date ale parametrilor, in cazul claselor template trebuie sa specificam de fiecare data, cand ne referim la ele, intre `<` si `>` tipurile de date ce inlocuiesc tipurile generice. | ||
De exemplu, pentru clasa `A`, vom scrie: | ||
```cpp | ||
A<int,float,...> | ||
``` | ||
(*A de `int` `float` `...`*) | ||
|
||
```cpp | ||
template <class T> | ||
class Punct3D | ||
{ | ||
T x, y, z; | ||
public: | ||
Punct3D(T X, T Y, T Z) | ||
{x = X; y = Y; z = Z;} | ||
T abs(){return x*x + y*y + z*z;} | ||
}; | ||
|
||
void main() | ||
{ | ||
Punct3D<int> p1(1,2,3); | ||
cout << p1.abs() << endl; | ||
Punct3D<float> p2(1,0.5,2); | ||
cout << p2.abs() << endl; | ||
} | ||
``` | ||
Toate functiile membre unei clase template devin la randul lor functii template. | ||
|
||
## Ierarhia `ios` | ||
`ios` - *input output stream standard* | ||
Ierarhia este pornita de clasa `ios`. | ||
Clasa `ios` porneste ierarhia, contine o serie de facilitati comune intregii ierarhii, in schimb nu se instantiaza direct. Clase aflate pe pozitii mai jos se instantiaza efectiv pentru a prelucra fluxul. | ||
Ierarhia `ios` foloseste instante de obiecte ale ierarhiei `streambuf` atunci cand fluxurile sunt prelucrate. Un obiect instanta din ierarhia `streambuf` gestioneaza buffer-ul atasat fluxului. | ||
Din cauza ca atunci cand prelucram un flux prin intermediului unui obiect instanta clasei `ios` si implementarea claselor a fost facut incat un obiect `streambuf` este gestionat automat, nu este necesar sa cunoastem membrii claselor `streambuf`, fiind suficient a cunoaste membrii claselor `ios`. Din clasa `streambuf` sunt derivate clasele `filebuf` (fiind specializata pe buffere atasate fisierelor) si `strstreambuf` (fiind specializata pe buffere pentru stringuri). | ||
Clasa `ios` are doi constructori: `ios()` si `ios(streambuf* buf)`. | ||
Clasa `ios` contine urmatoarele campuri: | ||
- `adjustfield`: este un camp constant static transmis de obicei in al doilea parametru al functiei `setf`; aceasta constanta este folosita pentru curatatea bitilor de formatare legati de aliniere (`left` sau `right`). | ||
- `basefield`: este un camp static constanta de tip `long` si este folosit pentru caratarea bitilor de formatare pentru bazele de numeratie. | ||
- `floatfield`: constanta statica de tip `long` pentru curatarea bitilor de formatare cu virgula mobila (reale). | ||
- `bp`: memoreaza adresa buffer-ului atasat fluxului, adica obiectul instanta `streambuf`. | ||
- `state`: este o valoare de tip `int` ce memoreaza starea fluxului; bitii acestui camp daca sunt `1` inseamna ca au aparut erori in prelucrarea fluxului si dau informatii cu privire la tipul erorii. | ||
- `x_fill`: o valoare de tip `int` care este folosit pentru caracterul pentru umplerea spatiilor libere | ||
- `x_flags`: o valoare de tip `long` ce retine bitii de formatare la scriere (aliniere, baze de numeratie, etc.) | ||
- `x_precision`: o valoare de tip `long` care retine precizia de afisare in virgula mobila a numerelor reale, adica numarul de cifre exacte folosite la afisare. | ||
- `x_width`: valoare `int` ce retine numarul de caractere pe care se face afisarea. | ||
|
||
Campurile care nu sunt constante de mai sus nu sunt publice. Aceste campuri se modifica folosind functii ale clasei `ios` sau ale claselor derivate din `ios`. | ||
Functiile membre clasei `ios`: | ||
- `int bad()`: returneaza o valoare nenula atunci cand in prelucrarea fluxului au aparut erori; sunt interogati bitii `ios::badbit` si `ios::hardfail`. | ||
- `int fail()`: returneaza o valoare nenula daca au aparut erori in prelucrarea fluxului, interogandu-se in plus fata de `int bad()` si bitul `ios::failbit`. | ||
- `int good()`: returneaza `1` daca nu au aparut erori in prelucrarea fluxului. | ||
- `void clear(int st=0)`: aduce fluxul din nou in stare buna; campul `state` al parametrului, implicit `0`, evident cand nu exista erori. | ||
- `char fill()`: returneaza caracterul folosit pentru caracterul care umple spatiile libere, adica returneaza valoarea lui `x_fill`. | ||
- `char fill(char c)`: seteaza noul caracter al lui `x_fill` cu valoarea lui `c` si returneaza vechiul caracter al `x_fill`. | ||
- `long iosflags()`: returneaza valoare campului `x_flags`. | ||
- `long iosflags(long f)`: seteaza noua valoare a lui `x_flags` cu valoarea lui `f` si returneaza vechea valoare a lui `x_flags`. | ||
- `void init(streambuf* buf)`: specificam adresa unui buffer ce se ataseaza fluxului curent. | ||
- `int precision()`: returneaza precizia de afisare a numerelor reale. | ||
- `int precision(int p)`: seteaza precizia `x_precision` la valoarea lui `p` si se returneaza vechea valoare a lui `x_precision`. | ||
- `stringbuf* rdbuf()`: returneaza adresa catre buffer-ul fluxului. | ||
- `int rdstate()`: returneaza valoarea lui `state`. | ||
- `int setstate(int s)`: campul `state` devine `s`. | ||
- `long setf(long flags`: bitii `1` ai variabilei `x_flags` fac sa devina biti `1` pe pozitiile corespunzatoare in campul `x_flags` si se returneaza vechea valoare a campului `x_flags`. | ||
- `long setf(long flags,long field)`: reseteaza bitii (ii face 0) din `x_flags` pe pozitiile indicate de bitii cu valoare `1` ai parametrului `field` si seteaza bitii din `x_flags` la valoarea `1` pe pozitiile in care bitii sunt `1` in parametrul `flags`, returnand valoarea campului `x_flags` inainte de modificare. | ||
- `long unsetf(long l)`: bitii `1` ai variabilei `l` anuleaza setari din campul `x_flags`. | ||
- `void sync_width_stdin()`: fluxul `ios` este sincronizat cu fluxul standard de intrare din C; sincronizarea incetineste executia. | ||
- `ostream* tie()`: este returnata adresa fluxului legat de fluxul curent; de exemplu, fluxul `cin` este legat de `cout`. | ||
- `ostream* tie(ostream* f)`: fluxul curent este legat de adresa data ca parametru, returnandu-se vechea legatura. | ||
- `int width()`: returneaza valoarea campului `x_width`. | ||
- `int width(int w)`: este setata lungimea la afisarea formatata, returnandu-se vechea lungime. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters