a c++11 újdonságai. smidla józsef operációkutatási laboratórium 2014. október 9
DESCRIPTION
C++11TRANSCRIPT
-
A C++11 jdonsgai
Smidla Jzsef
Opercikutatsi Laboratrium
2014. oktber 9.
1
-
Tartalom
nyers string auto, decltype nullptr constexpr foreach jdonsgok osztlyokban tpusos enum lambda kifejezsek struktra inicializls inicializl lista smart pointerek szlkezels
2
-
A C++11 szabvny
A szabvny 2011 szeptemberben jelent meg
Ha a gcc-t hasznljuk, akkor rdemes legalbb a 4.8.1-s verzit hasznlni
A gcc alapesetben mg a 2003-as szabvnyt tmogatja
Adjuk meg a fordtnak a std=c++11 kapcsolt!
A nyelv azta is fejldik, a legjabb szabvny a 2014-es
Jelen eladsnak nem clja, hogy teljes ttekintst nyjtson a C++11-rl
3
-
Nyers stringek
Hagyomnyos stringek:
cout
-
Nyers stringek
Hagyomnyos stringek:
cout
-
Nyers stringek
A nyers stringek gy troldnak, ahogy azokat bertuk a forrskdba:
sszetettebb hatrol karaktersorozat: cout
-
auto, decltype
Adott egy sszetett trol: std::map m;
7
-
auto, decltype
Adott egy sszetett trol: std::map m;
Jrjuk vgig egy itertorral:
std::map::iterator iter = m.begin();
8
-
auto, decltype
Adott egy sszetett trol: std::map m;
Jrjuk vgig egy itertorral:
std::map::iterator iter = m.begin();
Hasznljuk az auto kulcsszt: auto iter = m.begin();
Majd a fordt kitallja az iter tpust az m.begin() visszatrsi rtknek tpusbl.
9
-
auto, decltype
Vltoz, visszatrsi rtk tpusnak lekrdezse: int x;
decltype(x) y = 5;
Fleg templatek hasznlatakor lehet nagyon hasznos.
10
-
nullptr
A nullpointer hagyomnyosan: 0 vagy NULL #ifndef __cplusplus #define NULL ((void *)0) #else /* C++ */ #define NULL 0 #endif /* C++ */
Azaz, C++-ban a NULL tpusa int! Melyik fggvny hvdik meg? void foo(int) {} void foo(char *) {} [...] foo(NULL);
11
-
nullptr
Megolds: A C++11-ben bevezettk a nullptr kulcsszt.
Implicit kasztolhat ms pointerre s boolra.
Sajt tpusa van: decltype(nullptr), vagy
std::nullptr_t
rhatunk olyan fggvnyt, amely csak nullptr paramtert fogad el:
void foo(std::nullptr_t) {}
12
-
constexpr
Szmtsuk ki egy egsz szm kettes alap logaritmust metaprogramozssal:
13
-
constexpr
Szmtsuk ki egy egsz szm kettes alap logaritmust metaprogramozssal:
template
struct Logarithm {
enum { value = 1 + Logarithm::value };
};
template
struct Logarithm {
enum { value = 0 };
}; cout
-
constexpr
Szmtsuk ki egy egsz szm kettes alap logaritmust metaprogramozssal:
template
struct Logarithm {
enum { value = 1 + Logarithm::value };
};
template
struct Logarithm {
enum { value = 0 };
}; cout
-
foreach
rassuk ki egy vector minden elemt: vector v;
[]
auto iter = v.begin();
auto iterEnd = v.end();
for (; iter != iterEnd; iter++) {
cout
-
foreach
rassuk ki egy vector minden elemt: vector v;
[]
auto iter = v.begin();
auto iterEnd = v.end();
for (; iter != iterEnd; iter++) {
cout
-
foreach
Nveljk egy vector minden elemt: vector v;
[]
auto iter = v.begin();
auto iterEnd = v.end();
for (; iter != iterEnd; iter++) {
cout
-
foreach
Nveljk egy vector minden elemt: vector v;
[]
auto iter = v.begin();
auto iterEnd = v.end();
for (; iter != iterEnd; iter++) {
cout
-
foreach
A foreach sajt osztlyra is mkdik, ha:
Az osztlynak van begin() s end() fggvnye
Ezen fggvnyek valamilyen itertort adnak vissza
Az itertor rendelkezik ++, != s * (indirekci) opertorokkal
20
-
jdonsgok osztlyokban: rtkads deklarciban
Adattagnak rtkads deklarciban: class Person {
private:
int age = 20;
string name = "Dave";
};
Amennyiben a konstruktorban nem adunk rtket valamely vltoznak, a deklarciban megadott rtkeket veszi fel.
21
-
jdonsgok osztlyokban: delete fggvny
Bizonyos fggvnyek meghvsa letilthat: class Person {
public:
void foo() = delete;
void foo(int) {}
template void foo(T) =
delete;
};
A fenti pldban csak int tpus paramterrel hvhatjuk meg a foo fggvnyt!
Tovbbi plda: Letilthat a msol konstruktor, rtkad opertor is.
22
-
jdonsgok osztlyokban: move konstruktor
Balrtk: Minden olyan kifejezs, amely megcmezhet, s rtket adhatunk neki
a = 1; // a itt most balrtk
Jobbrtk: Ideiglenes objektum string getName() {
return "Joe";
}
string name = getName();
Itt a name balrtk, viszont a visszatrsi rtk jobbrtk
23
-
jdonsgok osztlyokban: move konstruktor
Balrtk referencia: tpus & nv Jobbrtk referencia: tpus && nv string name1 = getName(); string & name2 = getName(); const string & name3 = getName(); string && name4 = getName(); const string && name5 = getName();
A jobbrtk referencival hivatkozhatunk az ideiglenes objektumra
Balrtk referencibl jobbrtk referencia: Vector v; Vector && vr = std::move(v);
24
-
jdonsgok osztlyokban: move konstruktor
Mi trtnik ekkor? string getName() {
return "Joe";
}
string name = getName();
25
-
jdonsgok osztlyokban: move konstruktor
Mi trtnik ekkor? string getName() {
return "Joe"; }
string name = getName();
Ltrejn egy ideiglenes, string tpus objektum (konstruktor, memriafoglals, msols)
26
-
jdonsgok osztlyokban: move konstruktor
Mi trtnik ekkor? string getName() {
return "Joe";
}
string name = getName();
Meghvdik a copy konstruktor, s ltrejn a name objektum: jabb memriafoglals, msols
Vgl az ideiglenes objektum felszabadul 27
-
jdonsgok osztlyokban: move konstruktor
Csak egyszer foglaljunk memrit!
Nem lemsoljuk a visszatrsi rtket, hanem tmozgatjuk -> move konstruktor
Paramtere: egy jobbrtk referencia
Tipikus hasznlata: Lemsoljuk az adattagokat (a pointereket is), majd az eredeti objektum vltozit kinullzzuk
Az objektumot tmozgattuk, az eredeti objektumnl a destruktor nem csinl semmit
28
-
jdonsgok osztlyokban: move konstruktor
class Vector {
public:
Vector() {
data = new double[10];
}
Vector(Vector && right) {
data = right.data;
right.data = nullptr;
}
~Vector() {
delete [] data;
data = nullptr;
}
private:
double * data;
}; 29
-
jdonsgok osztlyokban: move konstruktor
Vector getVector() {
Vector v;
return v;
}
int main() {
Vector v0 = getVector();
}
Lefut a Vector konstruktora, az pedig lefoglalja a dinamikus tmbt.
3, 5, 4, 3, 1, 0, 1, 6, 7, 8, 2, 10
v
data
30
-
jdonsgok osztlyokban: move konstruktor
Vector getVector() {
Vector v;
return v;
}
int main() {
Vector v0 = getVector();
}
Ltrejn egy ideiglenes objektum, ez a move konstruktor ltal jn ltre.
3, 5, 4, 3, 1, 0, 1, 6, 7, 8, 2, 10
v
data
data ?
31
-
jdonsgok osztlyokban: move konstruktor
Vector(Vector && right) {
data = right.data;
right.data = nullptr;
}
Az jonnan ltrejv objektum lemsolja a pointert.
3, 5, 4, 3, 1, 0, 1, 6, 7, 8, 2, 10
v=right
data
data
32
-
jdonsgok osztlyokban: move konstruktor
Vector(Vector && right) {
data = right.data;
right.data = nullptr;
}
A rgi objektum pointert nullzzuk, hiszen az gyis felszabadul.
3, 5, 4, 3, 1, 0, 1, 6, 7, 8, 2, 10
v=right
data
data
33
-
jdonsgok osztlyokban: move konstruktor
Vector getVector() {
Vector v;
return v;
}
int main() {
Vector v0 = getVector();
}
Ltrejn a v0 vltoz, mgpedig szintn egy move konstruktor hvssal, ahol most az elbb ltrejtt vektor lesz a konstruktor paramtere
3, 5, 4, 3, 1, 0, 1, 6, 7, 8, 2, 10
data
v0
data
34
-
jdonsgok osztlyokban: move konstruktor
Vector(Vector && right) {
data = right.data;
right.data = nullptr;
}
int main() {
Vector v0 = getVector();
}
Lemsoljuk a pointert.
3, 5, 4, 3, 1, 0, 1, 6, 7, 8, 2, 10
right
data
v0
data
35
-
jdonsgok osztlyokban: move konstruktor
Vector(Vector && right) {
data = right.data;
right.data = nullptr;
}
int main() {
Vector v0 = getVector();
}
Majd nullzzuk az ideiglenes objektum pointert, hiszen gyis felszabadul.
3, 5, 4, 3, 1, 0, 1, 6, 7, 8, 2, 10
right
data
v0
data
36
-
jdonsgok osztlyokban: move = opertor
Ha a visszatrsi rtket olyan vltozban troljuk, amely mr ltezik, akkor az = opertor fut le
Ltezik move = opertor, amely szintn jobbrtk referencit kap paramterknt
A move konstruktornl annyiban tbb, hogy az aktulis vltoz tartalmt felszabadtja
37
-
jdonsgok osztlyokban: move = opertor
class Vector {
public:
[]
Vector & operator=(Vector && right) {
if (&right == this) {
return *this;
}
delete [] data;
data = right.data;
right.data = nullptr;
[]
}
38
-
Ekzben a gcc-ben
Gcc-t alaprtelmezett paramterekkel hasznlva az albbi kd esetben csak egy konstruktor s egy destruktor fut le: Vector getVec() {
Vector v;
return v;
}
int main() {
Vector vec = getVec();
A fordt optimalizl (copy elision)
Kikapcsolhat a -fno-elide-constructors kapcsolval (de nem rdemes )
39
-
Tpusos enum
Problma: enum GYUMOLCSOK {ALMA, KORTE, NARANCS};
enum SZINEK {PIROS, KEK, NARANCS};
A NARANCS kt enumban is szerepel
Megolds: enum class GYUMOLCSOK {ALMA, KORTE, NARANCS};
enum class SZINEK {PIROS, KEK, NARANCS};
enum class SZINEK szin = SZINEK::NARANCS;
Egyrtelmen kifejezhetjk, hogy az egyik enum tpus nem kompatibilis a msikkal
40
-
Az enum mrete
Az enum mrete alaprtelmezetten az int mretvel egyenl
A mret lecserlhet brmely egsz tpus mretre:
enum class GYUMOLCSOK : char {ALMA, KORTE};
41
-
Lambda kifejezsek
rjunk fggvnyt, amely megszmllja, hogy hny olyan elem van egy tmbben, amelyekre igaz egy bizonyos tulajdonsg!
A fggvny legyen ltalnos cl.
Rgi mdszerek:
Fggvny pointer tadsa
Funktorok alkalmazsa
42
-
Lambda kifejezsek
j mdszer: #include int szamol(int * v, int meret, std::function talalt) { int i; int mennyi = 0; for (i = 0; i < meret; i++) { if (talalt(v[i])) { mennyi++; } } return mennyi; } int main() { int vec[10] = {3, 5, 1, 3, 5, 1, 7, 8, 4, 1}; auto paros = [](int num)->bool{return num % 2 == 0;}; int parosak = szamol(vec, 10, paros); []
43
-
Lambda kifejezsek
Mskpp: #include int szamol(int * v, int meret, std::function talalt) { int i; int mennyi = 0; for (i = 0; i < meret; i++) { if (talalt(v[i])) { mennyi++; } } return mennyi; } int main() { int vec[10] = {3, 5, 1, 3, 5, 1, 7, 8, 4, 1}; int parosak = szamol(vec, 10, [](int num)->bool{ return num % 2 == 0; }); []
44
-
Lambda kifejezsek
Szintaktika:
[] () ->{}
Vltozk elfogsa: Segtsgvel a fggvnybl hivatkozhatunk olyan vltozkra, amelyek ott lteznek, ahol megrtuk a lambda kifejezst
45
-
Lambda kifejezsek
Plda vltozk elfogsra: int alma = 4;
int vec[10] = {3, 5, 1, 3, 5, 1, 7, 8, 4, 1};
int nagyok = szamol(vec, 10, [=](int num)->bool {
return num > 3+alma;
});
Az [=] jelentse: a fggvny megkapja minden, a lambda kifejezs krnyezetben elrhet vltoz msolatt
46
-
Lambda kifejezsek
Tovbbi lehetsgek vltozk elfogsra:
[] semmit nem kapunk el
[&] a vltozkat referencia szerint kapjuk el
[] egy konkrt vltozk kapunk el rtk szerint
[=, &] minden vltozt rtk szerint kapunk el, kivve egyet, amelyet referencia szerint
[this] a befoglal objektum cmt fogjuk el
47
-
Struktra inicializls
A struktrkat mostantl tmrebb formban is inicializlhatjuk: struct Valami {
int a;
char b;
double c;
};
struct Masik {
Valami v;
int d;
};
int main() {
Masik m = {{2, 'b', 4.4}, 4};
[]
48
-
Struktra inicializls
A struktrkat mostantl tmrebb formban is inicializlhatjuk: struct Valami {
int a;
char b;
double c;
};
struct Masik {
Valami v;
int d;
};
int main() {
Masik m = {{2, 'b', 4.4}, 4};
[]
49
-
Inicializl lista
Gyorsan tltsnk fel egy vectort nhny elemmel, rgi mdszer: std::vector v;
v.push_back(3);
v.push_back(2);
v.push_back(7);
j mdszer: std::vector v = {3, 2, 7};
50
-
Inicializl lista
A sajt osztlyunkat is felkszthetjk arra, hogy inicializl listt kap
A fordt felismeri az inicializl listt
A listt begyazza egy std::initializer_list tpus objektumba
Az objektumot pedig megkapja a fggvnynk paramterknt
51
-
Inicializl lista
Vector(const std::initializer_list & list) { data = new double[ list.size() ]; auto iter = list.begin(); auto iterEnd = list.end(); unsigned int index = 0; for (; iter != iterEnd; iter++, index++) { data[index] = *iter; } }
Vagy: Vector(const std::initializer_list & list) { data = new double[ list.size() ]; unsigned int index = 0; for (auto value: list) { data[index] = value; } }
}
52
-
Smart pointerek
Header: memory
Okos pointerek: korbban std::auto_ptr
Eltrol egy pointert, s ha a vltoz megsznik, automatikusan felszabadtja a pointer ltal mutatott objektumot
Ha lemsoljuk az objektumot, akkor a msolat trolja az eredeti pointert, az eredeti objektum nullpointert tartalmaz
53
-
Smart pointerek
std::auto_ptr ptr1(new Vector);
std::auto_ptr ptr2;
cout
-
Smart pointerek
std::unique_ptr: ugyanaz, mint az std::auto_ptr, csupn nem azt mondjuk hogy lemsoljuk a pointereket, hanem tmozgatjuk
A C++11-ben rvnytelentettnek szmt az std::auto_ptr
Az std::unique_ptr copy constructora s a = opertorok deleted fggvnyek
55
-
Smart pointerek
std::unique_ptr ptr1(new Vector);
std::unique_ptr ptr2;
cout
-
Smart pointerek
std::shared_ptr: Tbb shared_ptr kpes trolni ugyanazt a pointert, m referencia szmllst alkalmaz
Ha megsznik minden olyan shared_ptr, amely az adott objektumra hivatkozik, csak akkor szabadul fel a dinamikus objektum
Problma lehet abbl ha az objektumok krkrsen hivatkoznak egymsra
57
-
Smart pointerek
std::shared_ptr ptr1(new Vector);
std::shared_ptr ptr2;
cout
-
Smart pointerek
x hivatkozik y-ra, y pedig x-re, hiba trljk egyiket, vagy a msikat, letben tartjk egymst struct A {
~A() {
cout ptr = x;
59
-
Smart pointerek
std::weak_ptr: Ha az objektumra mr csak egy weak_ptr hivatkozik, akkor az az objektum felszabadul
Megtrhet a krkrs hivatozs
A weak_ptr lemsolhat egy shared_ptr-t
A shared_ptr csak a weak_ptr lock() fggvnyn keresztl msolhat le egy weak_ptr-t
Utbbi esetben mindig ellenrizni kell, hogy a msolat shared_ptr rvnyes memriaterletre mutat-e
60
-
Smart pointerek
A korbbi krkrs hivatkozs feloldsa: struct A {
~A() {
cout ptrWeak = x;
61
-
Szlkezels
j szlakat hozhatunk ltre az std::thread osztly segtsgvel Meg kell adnunk azt a fggvnyt, amelyet az j szl futtat
#include #include void foo() { std::cout
-
Szlkezels
Osztott vltozkat mutexekkel vdhetnk
A mutex is osztott
A szlak megprbljk lefoglalni a mutexet, de egyszerre csak egynek sikerl, a tbbi addig vrakozik int a = 0;
std::mutex m;
void foo() {
m.lock();
a = rand() % 10;
m.unlock();
}
63
-
Szlkezels
Egy statikus vltoz csak egy pldnyban ltezik
Minden szl ugyanazt a statikus vltozt ltja
A thread_local kulcsszval minden szl sajt pldnyt kap az adott statikus vltozbl
A thread_local vltoz a szl ltrehozsakor jn ltre, s a szl vgn megsemmisl
64
-
Szlkezels
thread_local hasznlatval: #include #include thread_local int b; class A { public: static thread_local int a; }; thread_local int A::a = 10; std::mutex m; void foo() { m.lock(); cout
-
Szlkezels
thread_local nlkl: #include #include int b; class A { public: static int a; }; int A::a = 10; std::mutex m; void foo() { m.lock(); cout
-
Ksznm a figyelmet!
67
A publikci az Eurpai Uni, Magyarorszg s az Eurpai Szocilis Alap trsfinanszrozsa ltal biztostott forrsbl a TMOP-4.2.2.C-11/1/KONV-2012-0004 azonostj "Nemzeti kutatkzpont fejlett
infokommunikcis technolgik kidolgozsra s piaci bevezetsre" cm projekt tmogatsval jtt ltre.