a c++11 újdonságai. smidla józsef operációkutatási laboratórium 2014. október 9

Upload: coyotesmith2

Post on 07-Jan-2016

220 views

Category:

Documents


0 download

DESCRIPTION

C++11

TRANSCRIPT

  • 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.