Funcția membru | Forma generală pentru clasa C : |
---|---|
Constructor implicit | C::C(); |
Destructor | C::~C(); |
Constructor de copiere | C::C (const C&); |
Copiere prin atribuire | C& operator= (const C&); |
Constructor de mutare | C::C (C&&); |
Atribuire prin mutare | C& operator= (C&&); |
|
|
Exemplu
are un constructor implicit. De aceea, obiectele acestei clase pot fi construite doar declarându-le, fără alte argumente:
|
|
|
|
int
. De aceea urmâtoarea declarație este corectă:
|
|
|
|
|
|
continutul lui bar: Exemplu |
Exemplu3
are un constructor implicit (adică, un constructor fără parametri) definit ca un bloc vid:
|
|
Exemplu3
fără parametri (așa cum a fost declarat foo
în acest exemplu). În mod normal, un asemenea constructor implicit este definit pentru toate clasele care nu au alți constructori, motiv pentru care nu este necesară definirea explicită. Dar în acest caz, Exemplu3
are deja un alt constructor:
|
|
void
. De asemenea, are ca nume chiar numele clasei, dar precedat de un simbol tilda (~
):
|
|
continutul lui bar: Exemplu |
Exemplu4
alocă spațiu pentru un string
. Acest spațiu va fi eliberat ulterior de către destructor.foo
și bar
momentul acesta are loc la sfârșitul lui main
.const
) și care poate fi apelat cu un singur argument de acel tip. De exemplu, pentru o clasă Clasa_mea
, constructorul de copiere poate avea semnătura:
|
|
|
|
|
|
Exemplu4
definită mai sus, deoarece conține pointeri pentru gestionarea memoriei. Pentru acea clasă, realizarea unei copii simple înseamnă copierea valorii pointerului, nu a conținutului său; adică ambele obiecte (copia și originalul) partajează un singur obiect string
(cele doua pointează spre același obiect), iar la un moment dat (la apelul constructorului) ambele obiecte vor încerca să șteargă același bloc de memorie, ceea ce foarte probabil va genera eșuarea programului în momentul execuției. Această problemă poate fi rezolvată definind următorul constructor de copiere care realizează o copie complexă:
|
|
continutul lui bar: Exemplu |
|
|
baz
este inițializat la construcție folosind un simbol equal, dar aceasta nu este o operație de atribuire! (deși seamănă cu așa ceva): declarația unui obiect nu este o operație de atribuire, este doar o altă formă pentru sintaxa de apelare a unui constructor cu un singur argument.foo
este o operație de atribuire. Aici nu este declarat niciun obiect, ci operația se execută cu un obiect existent - foo
.operator=
care ia ca parametru o valoare sau o referință a clasei. Valoarea returnată este, în general, o referință la *this
(deși nu este obligatoriu). De exemplu, pentru o clasă Clasa_mea
, copierea prin atribuire ar putea avea următoarea semnătură:
|
|
Exemplu5
. În acest caz, nu numai că apare riscul încercării de ștergere dublă a unui obiect, dar copierea prin atribuire creează probleme căci nu se poate șterge obiectul spre care se pointa înainte de atribuire. Asemenea situații-problemă se pot rezolva cu copierea prin atribuire care poate șterge obiectul anterior și executa o copie complexă:
|
|
string
nu este constant, s-ar putea reutiliza acelasi obiect string
:
|
|
|
|
fn
cât și valoarea construită cu Clasa_mea
sunt temporare anonime. În aceste situații, nu este necesară crearea unor copii, deoarece obiectul anonim are durata de viață foarte scurtă iar operația este mai eficientă astfel.
|
|
&&
). Ca parametru, o referință rvalue trebuie să aibă același tip cu argumentele temporare.
|
|
continutul lui foo: Exemplu |
Funcție membru | definitâ implicit: | definiție implicită: |
---|---|---|
Constructor implicit | dacă nu a fost definit alt constructor | nu face nimic |
Destructor | dacă nu există deja destructor | nu face nimic |
Constructor de copiere | dacă nu există constructor de mutare și nici mutare prin atribuire | copiază toți membrii |
Copiere prin atribuire | dacă nu există constructor de mutare și nici mutare prin atribuire | copiază toți membrii |
Constructor de mutare | dacă nu există destructor, nici constructor de copiere, nici copiere sau mutare prin atribuire | mută toți membrii |
Mutare prin atribuire | dacă nu există destructor, nici constructor de copiere, nici copiere sau mutare prin atribuire | mută toți membrii |
default
, respectiv delete
. Sintaxa poate fi una dintre următoarele:function_declaration = default; function_declaration = delete; |
|
|
aria lui bar: 200 |
Dreptunghi
poate fi construit fie cu două argumente int
fie cu construcția implicită (fără argumente). Totuși, nu poate fi construit prin copiere din alt obiect Dreptunghi
, deoarece a fost ștearsă această funcție. De aceea, considerând obiectele din ultimul exemplu, urmatoarele instrucțiuni nu sunt valide:
|
|
|
|
|
|
default
, nu se definește o funcție membru echivalentă cu constructorul implicit (adică, unde default constructor să însemne constructor fără parametri), dar echivalentă cu constructorul care ar fi fost definit implicit dacă nu s-ar fi șters.delete
fie default
între funcțiile membru speciale care nu sunt definite explicit.Previous: Clase (II) | Index | Next: Prietenie și moștenire |