Documente Academic
Documente Profesional
Documente Cultură
C
++{};
C++ Acest curs
› Pointer la functii
› Functori (obiecte functii)
› Lvalue, rvalue
› Constructor de mutare
› Operator de asignare de mutare
› I/O
C++ Pointeri la functii (PF)
› Contine adresa de memorie a unei secvente de instructiuni
aflate in segmentul de cod.
› Dereferentierea unui astfel de pointer permite executia
secventei respective de instructiuni
› Dereferentierea permite si furnizarea de argumente daca
pointerul a fost declarat astfel
› Beneficiu: permite implementarea unui mechanism de
selectie a secventei de cod ce urmeaza a fi executate la
run-time.
type (*FunctionPointerName)(type param1, type param2, ...)
C++ Pointer la functii
#include <iostream>
using namespace std;
return 0;
}
int main(void)
{
double a = 5.4;
double b = 6.7;
BinaryFunction *add = new Add;
BinaryFunction *multiply = new Multiply;
delete add;
delete multiply; Add: 5.4, 6.7 = 12.1
return 0; Multiply: 5.4, 6.7 = 36.18
}
C++ Lvalues and Rvalues
C++
› glvalue – “generalized” lvalue – expresie a carei evaluare
determina identitatea unui obiect, bit-field, sau functie
› prvalue – “pure” rvalue – expresie a carei evaluare:
– calculeaza valoarea operandului unui operator (nu are ca rezultat
un obiect).
– Initializeaza un obiect sau bit field
› xvalue – “eXpiring” value – gvalue ce indica un obiect sau
bit field ale carei resurse pot fi reutilizate
› lvalue – gvalue care nu este xvalue si apare in partea
stanga a operatorului de asignare
› rvalue – este prvalue sau xvalue
C++ lvalue
• a function call or an overloaded operator expression, whose return type is lvalue reference, such
as std::getline(std::cin, str), std::cout << 1, str1 = str2, or ++it;
• a = b, a += b, a %= b, and all other built-in assignment and compound assignment expressions;
• ++a and --a, the built-in pre-increment and pre-decrement expressions;
• *p, the built-in indirection expression;
• a[n] and p[n], the built-in subscript expressions, where one operand in a[n] is an array lvalue
(since C++11);
• a.m, the member of object expression, except where m is a member enumerator or a non-static
member function, or where a is an rvalue and m is a non-static data member of non-reference
type;
• p->m, the built-in member of pointer expression, except where m is a member enumerator or a
non-static member function;
• a.*mp, the pointer to member of object expression, where a is an lvalue and mp is a pointer to
data member;
• p->*mp, the built-in pointer to member of pointer expression, where mp is a pointer to data
member;
• a, b, the built-in comma expression, where b is an lvalue;
• a ? b : c, the ternary conditional expression for some b and c (e.g., when both are lvalues of the
same type, but see definition for detail);
C++ prvalue
• a literal (except for string literal), such as 42, true or nullptr;
• a function call or an overloaded operator expression, whose return type is non-reference, such
as str.substr(1, 2), str1 + str2, or it++;
• a++ and a--, the built-in post-increment and post-decrement expressions;
• a + b, a % b, a & b, a << b, and all other built-in arithmetic expressions;
• a && b, a || b, !a, the built-in logical expressions;
• a < b, a == b, a >= b, and all other built-in comparison expressions;
• &a, the built-in address-of expression;
• a.m, the member of object expression, where m is a member enumerator or a non-static member
function[2], or where a is an rvalue and m is a non-static data member of non-reference type
(until C++11);
• p->m, the built-in member of pointer expression, where m is a member enumerator or a non-
static member function[2];
• a.*mp, the pointer to member of object expression, where mp is a pointer to member function[2],
or where a is an rvalue and mp is a pointer to data member (until C++11);
• p->*mp, the built-in pointer to member of pointer expression, where mp is a pointer to member
function[2];
• a, b, the built-in comma expression, where b is an rvalue;
• a ? b : c, the ternary conditional expression for some b and c (see definition for detail);
C++ xvalue
• a function call or an overloaded operator expression, whose return type is rvalue reference to
object, such as std::move(x);
• a[n], the built-in subscript expression, where one operand is an array rvalue;
• a.m, the member of object expression, where a is an rvalue and m is a non-static data member
of non-reference type;
• a.*mp, the pointer to member of object expression, where a is an rvalue and mp is a pointer to
data member;
• a ? b : c, the ternary conditional expression for some b and c (see definition for detail);
C++ gvalue
A glvalue expression is either lvalue or xvalue.
rvalue
An rvalue expression is either prvalue or xvalue.
https://en.cppreference.com/w/cpp/language/value_category
C++ Lvalue Reference Declarator: &
type-id & cast-expression
› Fie urmatoarea secventa
int x = 5, y;
y = x + 2;
y este lvalue
x + 2 este rvalue
int F(int&& n)
{
std::cout << " Apel cu parametru referinta rvalue, resultaul este: ";
return 2 * n;
}
int main()
{
int x = 6;
std::cout << F(x) << '\n';
std::cout << F(x + 2) << '\n';
std::cout << F(6) << '\n';
Distrugere temporar
Distrugere myList
C++
› Avand in vedere ca in declararea constructorului de copiere
regasim parametrul const IntList&, va accepta obiectul
temporar. Acest obiect temporar este este returnat de functia
MakeList si este o copie a obiectului local result de tip
IntList returnat de functie.
› Obiectul result este un obiect tranzitoriu si nu se recomanda
a se crea o copie a unui astfel de obiect deoarece construirea
si distrugerea obiectului temporar sunt consumatoare de timp.
class IntList
{
class Node
C++ {
public:
int data; // elementrul data al listei
Node *next; // adresa urmatorului nod din lista
Node(int d); // Constructor
~Node(); // Destructor
};
Node *head; // adresa primului alement din lista
Node *tail; // adresa ultimului element din lista
int len; // numarul elementelor din lista
public:
IntList(); // Constructor, creaza o lista goala
~IntList(); // Destructor, dealoca spatial de memorie ocupat de lista
IntList(const IntList& c); // Constructor de copiere
IntList& operator=(const IntList& other); // operator de asignare de copiere
IntList(IntList&& c); // Constructor de mutare
IntList& operator=(IntList&& other); // operator de asignare de mutare
void Insert(int n); // inserare la sfarsitul listei
void Print() const; // afiseaza elementele listei
int Length() const; // returneaza numerul de elemente din lista
void Clear(); // elimina toate elementele din lista.
};
C++
› Resolvarea ambiguitatii:
– Daca apelantul furnizeaza lvalue, compilatorul genereaza cod ce
invoca constructorul de copiere sau operatorul de asignare de copiere
– Daca apelantul furnizeaza rvalue, compilatorul genereaza cod ce
invoca constructorul de mutare sau operatorul de asignare de mutare
› Scopul constructorul de mutare este de a muta resursele unui
obiect temporar intr-un obiect nou creat (pentru a evita
crearea unei copii a unui temporar).
› Similar, scopul operatorului de asignare de mutare este de a
muta resursele unui obiect temporar intr-un obiect existent
fara a crea un nou obiect.
C++
› Este in regula sa “”furam” resursele unui obiect temporar
deoarece acel obiect este transitoriu si nu mai poate fi folosit
mai tarziu in program.
› Atunci cand viata “efemera” a obiectului tranzitoriu se
“termina” va fi apelat apelat destructorul aferent. Din acest
motiv atat constructorul de mutare cat si operatorul de
asignare de mutare trebuie sa lase respectivul obiect
temporar intr-o stare bine definita. Acesta este si motivul
pentru care parametrul ambelor functii nu este const.
// exemplu de implementare constructor de mutare
IntList::IntList(IntList&& temp): IntList()
C++ {
// Swap contents with the temporary
std::swap(head, temp.head);
std::swap(tail, temp.tail);
std::swap(len, temp.len);
}
IntList MakeList(int n)
{
IntList result;
for (int i = 0; i < n; i++)
result.Insert(i); Creating node 0 (21169512)
return result; Creating node 1 (21214272)
} Creating node 2 (21214512)
Creating node 3 (21214304)
int main() Creating node 4 (21214208)
{ 0 1 2 3 4
auto myList = MakeList(5); Destroying node 4 (21214208)
myList.Print(); Destroying node 3 (21214304)
} Destroying node 2 (21214512)
Destroying node 1 (21214272)
Destroying node 0 (21169512)
C++ I/O
› Limbajul C++ nu are instructiuni specifice operațiilor de intrare/ieșire
› La baza operațiilor I/O se află conceptul de stream (flux). Prin stream se
intelege un flux de date de la o sursă la o destinație sau consumator
– sursa – tastatura, fisier pe disc, zona de memorie
– destinatie – monitor, fisier pe disc, zona de memorie
› C++ conține două ierarhii de clase: una are ca radacina clasa streambuf,
iar cealaltă, clasa ios
› streambuf – furnizează funcții generale pentru lucrul cu zonele tampon
(buffers) și permite tratarea operațiilor de intrare/ieșire fără formatări
complexe. Clase derivate – strstreambuf și filebuf
C++
C++
› Clasa ios are un pointer spre streambuf. Contine membri pentru a
controla interfața streambuf și pentru tratarea erorilor. Clase derivate:
istream pentru gestiunea intrărilor și ostream pentru gestiunea iesirilor
class istream : virtual public ios
class ostream : virtual public ios
cout.width(5);
printf("%05d", i);
cout.fill(‘0’);
cout << i;
C++ Indicatori de format
› Sunt definiti in clasa ios si reprezinta biti din dublul cuvant x_flag,
membru al clasei
public enum
{
skipws=0x0001, //Skip white space on input.
left=0x0002, //Left-align values; pad on the right with the fill character.
right=0x0004, //Right-align values; pad on the left with the fill character (default alignment).
internal=0x0008, //Add fill characters after any leading sign or base indication, but before the
value.
dec=0x0010, //Format numeric values as base 10 (decimal) (default radix).
oct=0x0020, //Format numeric values as base 8 (octal).
hex=0x0040, //Format numeric values as base 16 (hexadecimal).
showbase=0x0080, //Display numeric constants in a format that can be read by the C++ compiler.
showpoint=0x0100, //Show decimal point and trailing zeros for floating-point values.
uppercase=0x0200, //Display uppercase A through F for hexadecimal values and E for scientific
values.
showpos=0x0400, //Show plus signs (+) for positive values.
scientific=0x0800, //Display floating-point numbers in scientific format.
fixed=0x1000, //Display floating-point numbers in fixed format.
unitbuf=0x2000, //Cause ostream::osfx to flush the stream after each insertion. By default, cerr
is unit buffered.
stdio=0x4000, //Cause ostream::osfx to flush stdout and stderr after each insertion.
};
C++
› Indicatorii mai sus enumerati sunt grupati in trei grupe:
– adjustfiled – right, left si internal – defineste pozitiile caracterelor de
umplere
– basefield – dec, oct si hex – defineste baza de numeratie
– floatfield – scientific, fixed – definesc formatul de afisare
› In cadrul unei grupe numai un bit poate fi setat
› Biti indicatori de format pot fi setati prin intermediul functiei setf membra a
clasei ios
long setf(long f);
long setf(long bit, long grupa);
int i = 123;
cout.width(5);
cout.fill(' ');
cout.setf(ios::left, ios:adjustfield);
cout.setf(ios::showpos);
cout << i;
C++ Manipulatori
› Permit definirea formatelor pentru operatiile de intrare/iesire.
› Sunt functii membru speciale ce returneaza o referinta la un stream. In
acest fel apelurile manipulatorilor se pot inlantui.
› Practic, facilitatile oferite de functiile width, setf, fill etc. pot fi realizate
cu ajutorul manipulatorilor
Manipulator Actiune
dec Seteaza indicatorul de conversie in zecimal
oct Seteaza indicatorul de conversie in octal
hex Seteaza indicatorul de conversie in hexazecimal
ws Seteaza indicatorul skipws de salt peste caracterele
albe
endl Insereaza newline si videaza zona tampon a streamului
ends Insereaza caracterul nul
flush Videaza zona tampon a unui obiect al clasei ostream
C++
Manipulator Actiune
setbase(int n) Seteaza baza dfe conversie egala cu n;//unde n poate avea una
din valorile 0, 8, 10 sau 16. Valoarea 0 inseamna conversie
implicita, adica in zecimal
resetiosflags(long f) Sterge biti de format specificati de parametrul f
setiosflags(long f) Seteaza bitii de format specificati de parametrul f
setfill(int n) Seteaza caracterul de umplere la valoarea lui n
setprecision(int n) Seteaza precizia la valoarea lui n
setw(int n) Seteaza dimensiunea campului la valoarea lui n
int i = 123;