Post on 26-Jan-2021
C++
C++
Pataki Norbert
Eötvös Loránd Tudományegyetem,Programozási Nyelvek és Fordítóprogramok
Tanszék, Budapestpatakino@elte.hu
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