pataki norbertpatakino.web.elte.hu/halado_c++/cpp.pdf · 2011. 7. 14. · pataki norbert eötvös...

85
C++ C++ Pataki Norbert Eötvös Loránd Tudományegyetem, Programozási Nyelvek és Fordítóprogramok Tanszék, Budapest [email protected] ELTE Nyári egyetem 2011

Upload: others

Post on 26-Jan-2021

7 views

Category:

Documents


0 download

TRANSCRIPT

  • C++

    C++

    Pataki Norbert

    Eötvös Loránd Tudományegyetem,Programozási Nyelvek és Fordítóprogramok

    Tanszék, [email protected]

    ELTE Nyári egyetem 2011

  • C++

    Tartalom

    Bevezetés

    Referenciák

    Objektum-orientált programozás

    Sablonok

    Standard Template Library

    Template Metaprogramozás

    C++0x

    Összefoglalás

  • C++

    Bevezetés

    A C++ alapjai

    I 1980-as évek óta; Bjarne StroustrupI C++ Szabvány: 1998/2003I C++0xI A C programozási nyelvre alapul; reverse kompatibilitásI HatékonyságI Multiparadigmás programozásI Fordítóprogramok: g++, Microsoft Visual Studio, Comeau,

    Intel, stb.

  • C++

    Bevezetés

    A C alapjai

    I Imperatív, procedurális programozásI Vezérlési szerkezetek, függvényekI Saját típusok: rekordokI szabványkönyvtár

  • C++

    Bevezetés

    Hello World

    #include

    int main(){printf( "Hello World!\n" );return 0;

    }

  • C++

    Bevezetés

    Bővítések C-hez képest

    I Függvény túlterhelésI Referenciák (álnevek)I Objektum-orientált paradigma: osztályok, polimorfizmus

    I OsztályokI ÖröklődésI Polimorfizmus

    I KivételkezelésI SablonokI Kényelmesebb, biztonságosabb, bővebb szabványkönyvtárI ...

  • C++

    Bevezetés

    Típusok

    I sizeof(char) az egységI sizeof(char) ≤ sizeof(short) ≤ sizeof(int) ≤sizeof(long)

    I sizeof(float) ≤ sizeof(double) ≤ sizeof(longdouble)

    I sizeof(bool) ≤ sizeof(long)

  • C++

    Bevezetés

    Fordítás menete

    I Preprocesszor: szövegátalakításI Nyelvi fordító: tárgykódok (object-ek) előállításI Linker: tárgykódok összefésülése

  • C++

    Bevezetés

    Hello World

    #include

    int main(){std::cout

  • C++

    Referenciák

    Referenciák koncepciója

    int i = 5; // tárterület lefoglalása és// azonosító hozzárendelése// a tárterülethez

    int& r = i; // azonosító hozzárendelése// a tárterülethez

  • C++

    Referenciák

    Referenciák

    I Valamilyen létező objektumnak az álneveI Kötelező inicializálniI Mindig ugyanannak az objektumnak az álneve, nem

    változhat meg, hogy mire hivatkozikI Nincs „nullreferencia”

  • C++

    Referenciák

    Referencia-szerinti paraméterátadás

    void f( int& i ){// ...

    }

    int x = 10;f( x ); // OKf( x+2 ); // ford.hibaf( 5 ); // ford.hiba

  • C++

    Referenciák

    Referencia-szerinti paraméterátadás

    I Az alprogram lokális változója (i) egy álneve (alias-a) ameghíváskor átadott paraméternek (x).

    I Nincs másolás: az eredeti változóval dolgozik azalprogram

    I A függvényhívás során, amikor a függvényben imegváltozik, akkor a külső x is megváltozik (hiszen a kettőugyanaz)

    I A függvényhívás után x értéke megváltozhat afüggvényhívás előtti állapothoz képest.

    I Információ közvetítése a hívó irányábaI Nincs létrehozási, másolási, felszabadítási költség

  • C++

    Referenciák

    Konstans referencia-szerinti paraméterátadás

    void f( const int& i ){// ...

    }

    int x = 10;f( x ); // OKf( x+2 ); // OKf( 5 ); // OK

  • C++

    Referenciák

    Konstans referencia-szerinti paraméterátadás

    I Az alprogram lokális változója (i) egy olyan álneve(alias-a) a meghíváskor átadott paraméternek (x), amelyenkeresztül nem változik meg az értéke.

    I Nincs másolás: az eredeti változóval dolgozik azalprogram

    I A függvényhívás után x értéke ugyanaz, mint afüggvényhívás előtti.

    I Nincs létrehozási, másolási, felszabadítási költség

  • C++

    Referenciák

    Példák

    void swap( int a, int b ){int tmp = a;a = b;b = tmp;

    }

    void swap( int& a, int& b ){int tmp = a;a = b;b = tmp;

    }

  • C++

    Objektum-orientált programozás

    Osztályok

    class Complex{double re;double im;

    };

  • C++

    Objektum-orientált programozás

    Osztályok, konstruktor

    class Complex{double re;double im;

    public:Complex( double r = 0.0, double i = 0.0 ){re = r;im = i;

    }};

  • C++

    Objektum-orientált programozás

    Konstruktorok

    int main(){Complex zero;Complex i( 0.0, 1.0 );Complex nc = zero;Complex seven( 7.0 );

    }

  • C++

    Objektum-orientált programozás

    Osztályok, tagfüggvények

    class Complex{double re, im;

    public:Complex( double r = 0.0, double i = 0.0 ){re = r;im = i;

    }

    double get_re() const { return re; }double get_im() const { return im; }

    };

  • C++

    Objektum-orientált programozás

    Osztályok, tagfüggvények

    Complex c( 5.32, 7.34 );std::cout

  • C++

    Objektum-orientált programozás

    Operátorok

    I Túlterhelhető (pl. operator+) ill. Nem túlterhelhetőoperátorok (pl. operator.)

    I Fix argumentumszám (kivétel operator())

  • C++

    Objektum-orientált programozás

    Operátorok

    Complex a( 2.1, 4.4 );Complex b( 4.2, 3.8 );Complex c = a + b;

    // a.operator+( b ) tagfüggvényként// operator+( a, b ) globálisként

    std::cout

  • C++

    Objektum-orientált programozás

    Hibás operátor

    class Complex{double re, im;

    public:// ...Complex operator+( const Complex& c ) const{

    return Complex( re + c.re, im + c.im );}

    };

  • C++

    Objektum-orientált programozás

    Hibás operátor

    Complex a( 8.13, 5.4 );Complex b = a + 7.3; // OK...

    // a.operator+( 7.3 )

    Complex b = 7.3 + a; // ?7.3.operator+( a );

  • C++

    Objektum-orientált programozás

    Operátorok

    class Complex{...};

    std::ostream& operator

  • C++

    Objektum-orientált programozás

    Öröklődés

    #include #include using namespace std;

    int main(){vector v( 5 ); // OKstring s1( 5 ); // ford. hibastring s2( 0 ); // futási hiba

    }

  • C++

    Objektum-orientált programozás

    Öröklődés

    class safe_string{std::string s;

    public:safe_string( const char* p ): s( p ? p : "" ){}

    void push_back( char t ) { s.push_back( t) };

    int size() const { return s.size(); }// ...

    };

  • C++

    Objektum-orientált programozás

    Öröklődés

    class safe_string: public std::string{public:safe_string( const char* p ): std::string( p ? p : "" )

    {}// konstruktorok nem öröklődnek...

    };

  • C++

    Objektum-orientált programozás

    Polimorfizmus

    struct Base{virtual void f() const{std::cout

  • C++

    Objektum-orientált programozás

    Polimorfizmus

    struct Der{virtual void f() const{std::cout

  • C++

    Objektum-orientált programozás

    Polimorfizmus

    Base* bp = new Base();

    bp->f();

    delete bp;bp = new Der();

    bp->f();

  • C++

    Sablonok

    Igény a sablonokra

    I Típussal (és egyéb fordítási idejű adatokkal)paraméterezés

    I Függvény és osztály sablonok létrehozása: nem kell előremegadni, hogy milyen típussal dolgozik a sablon

  • C++

    Sablonok

    Függvénysablonok

    template const T& max( const T& a, const T& b ){return a < b ? b : a;

    }

    ...

    std::cout

  • C++

    Sablonok

    Sablonok

    I Sablonok példányosítása fordítási időbenI ParaméterdedukcióI Nem generálódik kód, amíg nem példányosítjukI Típus megszorítások

  • C++

    Standard Template Library

    Az STL komponensei

    I KonténerekI AlgoritmusokI IterátorokI FunktorokI Adapterek

  • C++

    Standard Template Library

    Konténerek STL-ben

    I Szekvenciális: vector, list, dequeI Asszociatív: set, multiset, map, multimap

  • C++

    Standard Template Library

    vector

    I Egybefüggő tárterületen azonos típusú elemek sorozataI Elemek indexelve (0-tól kezdve)I Elemek elérése – gyorsI Elem beszúrása vector végére – gyorsI Elem beszúrása máshova – lassabban

  • C++

    Standard Template Library

    vector

    #include using namespace std;

    vector v; // üres vector létrehozásav.push_back(4); // elem beszúrása vector végérev.pop_back(); // utolsó elem törlése

    // Ötelem"u vector létrehozása, minden eleme 3.2vector vd(5, 3.2);int s = vd.size();

    vd[1] = 4.76; // Elemek elérésevd.back() = 4.17; // Utolsó elem elérésevd.front() = 1.2; // Els"o elem elérése

  • C++

    Standard Template Library

    list

    I Elemek szétszórtan helyezkednek elI Elemek nincsen indexelveI i-edik elérése lassúI Elem beszúrása bárhova – gyorsI Következő / előző elem érhető el gyorsan

  • C++

    Standard Template Library

    list

    #include using namespace std;

    list l; // üres vector létrehozásal.push_front(4.5); // elem beszúrása lista elejérel.pop_front(); // utolsó elem törlésel.push_back(1.1); // elem beszúrása lista végére

    list vl(3, 6.32);int s = vl.size();

    l.back() = 4.17; // Utolsó elem elérésel.front() = 1.2; // Els"o elem elérésel.sort(); // Lista rendezésel.remove(1.2); // Adott értékek törlésel.reverse(); // Lista megfordítása

  • C++

    Standard Template Library

    deque

    I Kettős végű sorI Egybefüggő tárterületek szétszórtan helyezkednek elI Elemek indexelve vannakI Elemek elérése – gyorsI Elem beszúrása tároló elejére / végére – gyorsI Elem beszúrása közepére – lassabban

  • C++

    Standard Template Library

    deque

    #include #include using namespace std;

    deque d;d.push_front( "Hello" );d.push_back( "World" );d[0] = "Goodbye";d.back() = "Cruel World";d.pop_back();d.pop_front();

  • C++

    Standard Template Library

    set

    I Elemek sorrendje: rendezettségI Minden elem legfeljebb egyszer szerepelhetI Műveletek kihasználják a rendezettséget: gyors keresés,

    gyors beszúrás, stb.

  • C++

    Standard Template Library

    set

    #include #include using namespace std;

    srand(time(0));set nums;while( nums.size() < 5 ){nums.insert( (rand() % 90)+1 );

    }

  • C++

    Standard Template Library

    multiset

    I Elemek sorrendje: rendezettségI Azonos elemek többször is szerepelhetnekI Műveletek kihasználják a rendezettséget: gyors keresés,

    gyors beszúrás, stb.

  • C++

    Standard Template Library

    multiset

    #include using namespace std;

    multiset m;m.insert(3);

    int s = m.size();int i = m.count(3);

  • C++

    Standard Template Library

    map

    I Asszociatív tömb: elemek indexelveI Nem feltétlenül 0-tól kezdveI Nem feltétlenül egymás utáni indexekI Nem feltétlenül egészekI Kulcs alapján rendezett tárolás

  • C++

    Standard Template Library

    map

    #include #include #include using namespace std;

    map phones;phones["X.Y."] = "36(20)555-1234";phones["A.B."] = "36(30)555-5555";// ...cout

  • C++

    Standard Template Library

    Algoritmusok STL-ben

    I Konténer-független, újrafelhasználható, globálisfüggvénysablonok

    I Általánosítás (generalizáció), paraméterezhetőség, denem mehet a hatékonyság rovására

    I Megoldások gyakori feladatokraI Nem biztos, hogy egy algoritmus az összes konténerrel

    működikI Pl. find, sort, count, for_each

  • C++

    Standard Template Library

    Iterátorok STL-ben

    I Konténerek bejárásaI Algoritmusok és konténerek közötti kapcsolat

    megteremtéseI Az iterátorok interface-e a pointer-aritmetikán alapul:

    I operator++, operator*, operator==, stb.

  • C++

    Standard Template Library

    Funktorok STL-ben

    I Egyszerű felhasználói osztályok, amelyeknek vanoperator()-a

    I Ezen az operator()-on keresztül felhasználóikódrészletek hajtódnak végre a könyvtáron belül

    I Tipikus alkalmazások: felhasználói rendezések,predikátumok, műveletek

    I Unáris, Bináris funktorokI Előny: inline-osítás, . . .

  • C++

    Standard Template Library

    Példa

    class Print{std::ostream& os;

    public:

    Print( std::ostream& o ): os ( o ) { }

    template void operator()( const T& t ){os

  • C++

    Standard Template Library

    Példa

    std::set sd;std::list ls;std::deque di;

    std::for_each( sd.begin(), sd.end(),Print( std::cout ) );

    std::for_each( ls.begin(), ls.end(),Print( std::cerr ) );

    std::for_each( di.begin(), di.end(),Print( std::cout ) );

  • C++

    Standard Template Library

    Példa

    struct is_even: std::unary_function{bool operator()( int i ) const{return 0 == i % 2;

    }};

  • C++

    Standard Template Library

    Példa

    std::list li;// ...std::list::iterator i =std::find_if( li.begin(),

    li.end(),is_even() );

    std::vector ve;// ...std::vector::iterator i =std::find_if( ve.begin(),

    ve.end(),std::not1( is_even() ) );

  • C++

    Standard Template Library

    Példa

    template struct Less: std::binary_function{bool operator()( const T& a, const T& b ) const{return a < b;

    }};

  • C++

    Standard Template Library

    Példa

    std::set a;

    std::vector v;//...v.erase(std::remove_if(v.begin(),v.end(),std::bind2nd( Less(), 5.5 )

    ),v.end()

    );

  • C++

    Standard Template Library

    Spec. iterátorok

    // másoljuk a std.input-ot std.output-ra...std::copy(std::istreambuf_iterator( cin ),std::istreambuf_iterator(),std::ostreambuf_iterator( cout ) );

  • C++

    Standard Template Library

    Inserterek motivációja

    const int N = 10;double v[N];...double cv[N];

    // v másolása cv-be:copy( v, v + N, cv );

    // ez általában nem m"uködik a valódi STL// konténerek esetében...

  • C++

    Standard Template Library

    copy implementációja

    template OutIt copy( InIt first, InIt last, OutIt dest ){while ( first != last ){

    *dest++ = *first++;}return dest;

    }

  • C++

    Standard Template Library

    back_inserter

    double f( double x ){// ...

    }

    list values;...vector results;

    // f-et alkalmazzuk values összes elemére, és az// adatokat results végére szúrjuk:transform( values.begin(), values.end(),

    back_inserter( results ), f);

  • C++

    Standard Template Library

    front_inserter

    double f(double x){...}

    list values;...list results;

    // f-et alkalmazzuk values összes elemére, és// az adatokat results elejére szúrjuk:transform( values.begin(), values.end(),

    front_inserter( results ), f);

  • C++

    Standard Template Library

    inserter

    double f(double x){

    // ...}

    list values;// ...vector results;

    // f-et alkalmazzuk values összes elemére, és az// adatokat results közepére szúrjuk:transform (

    values.begin(), values.end(),inserter( results,

    results.begin() + results.size() / 2 ),f

    );

  • C++

    Standard Template Library

    inserter

    double f(double x){

    // ...}

    list values;// ...multiset results;

    // f-et alkalmazzuk values összes elemére, és// az adatokat results-ba szúrjuk (rendezett lesz)transform( values.begin(), values.end(),

    inserter( results, results.begin() ), f );

  • C++

    Standard Template Library

    back_inserter implementációja (vázlat)

    template class back_insert_iterator{

    Cont* c;public:

    back_insert_iterator(Cont& cont): c(&cont) { }

    back_insert_iterator& operator++(){return *this;

    }

    back_insert_iterator& operator++( int ){return *this;

    }

  • C++

    Standard Template Library

    back_inserter implementációja (vázlat)

    back_insert_iterator&operator=( typename Cont::const_reference d )

    // const typename Cont::value_type& d{c->push_back(d);return *this;

    }

    back_insert_iterator& operator*(){return *this;

    }};

  • C++

    Standard Template Library

    back_inserter implementációja (vázlat)

    template back_insert_iterator back_inserter( Cont& c ){return back_insert_iterator( c );

    }

  • C++

    Template Metaprogramozás

    Template Metaprogramozás

    I Fordítási időben végrehajtodó kódokI Rekurzív példányosítások, specializációk: Turing-teljes

    eszközI Optimalizációk, fordítási idejű ellenőrzések

  • C++

    Template Metaprogramozás

    Példa

    template struct Factorial{enum { Value = N * Factorial::Value };

    };template struct Factorial{enum { Value = 1 };

    };

    int main(){std::cout

  • C++

    Template Metaprogramozás

    Expression templates

    Array a, b, c, d, e;...e = a + b + c + d;// e = ( ( ( a + b ) + c ) + d );

    I Kényelmes, karbantarthatóI Lassú, pazarló

  • C++

    Template Metaprogramozás

    Rekurzív template-ek

    template class X { };

    X< X, X > fa;

  • C++

    Template Metaprogramozás

    Rekurzív template-ek

    struct plus{static double apply( double a, double b){return a+b;

    }};

  • C++

    Template Metaprogramozás

    Rekurzív template-ek

    template struct X{Left left;Right right;

    X( Left l, Right r) : left( l ), right( r ) { }

    double operator[](int i){return Op::apply( left[i], right[i] );

    }};

  • C++

    Template Metaprogramozás

    Array

    struct Array{// szokásos: adattagok, konstruktorok, stb.

    template void operator=( X expr){for ( int i = 0; i < N; ++i)

    arr[ i ] = expr[ i ];}

    };

  • C++

    Template Metaprogramozás

    Array

    template X operator+( Left a, Array b){

    return X(a,b);}

  • C++

    C++0x

    Szabványok

    I ISO/IEC 14882:1998I ISO/IEC 14882:2003I TR1, C++0x

  • C++

    C++0x

    C++0x újítások

    I Type inference: auto, decltypeI Lambda-kifejezésekI nullptr

    I variadikus template, template typedefI long long típusI PárhuzamosságI type traits, smart pointerek, hasító adatszerkezetekI . . .

  • C++

    C++0x

    Type inference

    std::map data;

    ...std::map::iterator i =

    data.begin();

  • C++

    C++0x

    Type inference

    std::map data;

    ...auto i = data.begin();

    auto two = 2;

    auto pi = 3.14;

  • C++

    C++0x

    Type inference

    const std::vector v(1);auto a = v[0];decltype( v[0] ) b = 1;

  • C++

    C++0x

    foreach

    int a[] = { 1, 2, 3, 4, 5 };for (int &i: a){

    i *= 2;}

  • C++

    C++0x

    Lambda függvény motivációja

    std::vector data;// ...int total = 0;std::for_each( data.begin(),

    data.end(),[&total]( int x ) { total += x; });

  • C++

    C++0x

    Lambda függvények

    I Funktor típus generálása a lambda függvény alapjánI A operator() visszatérési érték típusa: decltype( x+ y )

    [](int x, int y) { return x + y; }

    [](int x, int y) -> int{int z = x + y;return z + x;

    }

  • C++

    Összefoglalás

    Összefoglalás

    I A C++ multiparadigmás nyelvI Szabvány: 1998 óta, C++0xI C + osztályok + sablonok + ...,I Objektum-orientáltság: öröklődés, polimorfizmusI STL: generikus programozásI Template metaprogramozás

    Bevezetés

    Referenciák

    Objektum-orientált programozás

    Sablonok

    Standard Template Library

    Template Metaprogramozás

    C++0x

    Összefoglalás