Fejlett programozási nyelvek C++ Sablonok és adatfolyamok 11. előadás Antal Margit 2009 slide 1
Témakörök Sablonok Függvénysablon Osztálysablon Sablon metaprogramozás Adatfolyamok Operátorok és manipulátorok I/O műveletek: bináris és szöveges Fájlfolyamok Feladatok slide 2
Függvénysablon Függvénysablon : függvénycsalád fordítás idejű polimorfizmus template<class T> const T& max(const T& x, const T& y) { return x < y? y : x; template<class T> void swap(t& x, T& y) { const T tmp = x; x = y; y = tmp; slide 3
Osztálysablon Osztálysablon : osztálycsalád fordítás idejű polimorfizmus template<class T1, class T2> struct pair { ; typedef T1 first_type; typedef T2 second_type; T1 first; T2 second; pair(); pair(const T1& x, const T2& y);... slide 4
Példák template< class T1, class T2> pair<t1, T2> make_pair(const T1& x, const T2& y) { return pair<t1, T2>(x, y); template< class T> void swap( T& x, T& y){ const T tmp = x; x = y; y = tmp; slide 5
Sablonparaméterek (1) típus közönséges típus érték sablon template<class T, int MAX=100> class Stack{ ; T elements[ MAX ];... slide 6
Sablonparaméterek (2) template <class T, class CONT=vector<T> > class Stack{ CONT elements; public: void push( const T& e ){ elements.push_back( e );... ; slide 7
Tagfüggvények definíciója template<typename T> class Array { T* elements; int size; public: explicit Array(const int size);... ; template<typename T> Array<T>::Array(const int size) : size(size), elements(new T[size]){ slide 8
Példa: template < class T > void foo( const T& c, const char * str="") { typename T::const_iterator it; cout<<str; for(it = c.begin();it!= c.end(); ++it) cout<<*it<<' '; cout<<endl; slide 9
Sablon metaprogramozás Template Metaprogramming template<unsigned int N> struct Fact{ static const unsigned long int value = N * Fact<N-1>::value; ; template<> struct Fact<0>{ static const unsigned long int value = 1; ; // Fact<8> is computed at compile time: const unsigned long int fact_8 = Fact<8>::value; int main() { cout << fact_8 << endl; return 0; slide 10
Adatfolyamok - bevezetés AT&T alapozta meg az I/O standardot, amelyet a C++ könyvtár standardizálása előtt is használtak Módosítások történtek, de az alapelvek nem változtak slide 11
Adatfolyamok Program állomány billentyűzet program Bemeneti adatfolyam Kimeneti adatfolyam állomány képernyő program Alapvető adatfolyam-osztályok: istream ostream slide 12
Globális adatfolyam-objektumok cin istream, C stdin, billentyűzet cout ostream, C stdout, monitor, pufferelt cerr ostream, C stderr, monitor, nem pufferelt clog ostream, cerr-el megegyező eszközhöz csatolva, pufferelt slide 13
Operátorok és manipulátorok Operátorok: while( cin>>a>>b) cout<<a<<"\t"<<b<<"\n"; Manipulátorok: endl, ostream, '\n' kiírása + puffer ürítése ends, ostream, '\0' kiírása flush, ostream, puffer ürítése noskipws, istream, fehér karakterek olvasása slide 14
Manipulátorok char c; while( cin>>c ){ cout<<c<<":"<<(int)c<<endl; char c; cin >> noskipws; while( cin>>c ){ cout<<c<<":"<<(int)c<<endl; slide 15
Alapvető stream osztályok ios_base basic_streambuf<> streambuf, wstreambuf basic_ios<> ios, wios basic_istream<> istream, wistream basic_ostream<> ostream, wostream basic_iostream<> iostream, wiostream slide 16
Adatfolyamok állapota Adatfolyam objektum van állapota az adatfolyam állapotát a kapcsolók értékei határozzák meg: goodbit: minden rendben eofbit: fájl vége failbit: hiba, az utolsó I/O sikertelen badbit: végzetes hiba slide 17
Állapot-kezelő tagfüggvények good() rdstate() eof() clear() fail() clear(state) bad() setstate( state ) list<int> a; while(!cin.eof() ) { int x; cin>>x; a.push_back( x ); Bemenet: 1, 2, 3 Lista: 1, 2, 3, 3 slide 18
Felhasználói típusok írása/olvasása Operátorok túlterhelése: istream& operator>>( istream& is, T& v ){ //v beolvasása return is; ostream& operator<<(ostream& is,const T& v ) { //v kiíratása return os; slide 19
Fájlfolyamok { ifstream ifs("in.txt");//konstruktor if(!ifs ){//Hiba+kilépés //... //automatkusan megsemmisül-destruktor { ifstream ifs; ifs.open("in.txt"); //... ifs.close(); //... slide 20
Fájl megnyitási módok std::ios kapcsoló in out out trunc out app in out in out trunc jelentés csak olvasás (létező fájl) csak írás (létrehozza vagy üríti) csak írás (létrehozza vagy üríti) hozzáfűzés (létrehozza szükség esetén) írás és olvasás, csak létező fájl, kezdőpozíció: fájl eleje ürítés, írás és olvasás (létrehozza szükség esetén) slide 21
Fájl I/O bájtonként ifstream ifs("in.txt"); if(!ifs ){ cerr<<"hiba"<<endl; exit( 1 ); char c; while( ifs.get( c ) ) cout.put( c ); int get(); istream& get ( char& c ); istream& get ( char* s, streamsize n ); istream& get ( char* s, streamsize n, char delim ); istream& get ( streambuf& sb); istream& get ( streambuf`& sb, char delim ); slide 22
Formázott fájl I/O ifstream ifs("in.txt"); int i; double d; string s; ifs >> i >> d >> s;//elválasztók: fehér karakterek fstream f("out.txt", ios::in ios::out ios::trunc); for( int i=0; i<10; ++i ) f<<i<<endl; f.flush(); f.seekg(0, ios::beg); int x; while( f>>x) cout<<x<<endl; slide 23
Bináris I/O istream& read( char* buffer, streamsize count); ostream& write(const char* buffer, streamsize c); slide 24
Közvetlen elérés (Random Access) basic_istream<> ( g get ) tellg() seekg( pos ) seekg( offset, relative_position ) basic_ostream<> ( p - put) tellp() seekp( pos ) seekp( offset, realtive_position ) slide 25
Közvetlen elérés (Random Access) (folyt.) beg : beginning cur : current end : end Példák: file.seekg( 0, ios::beg) file.seekg( 20, ios::cur) file.seekg(-10, ios::end) slide 26
Indexelhető bemeneti adatfolyam myifstream f("be.txt"); for( int i=0; i<f.filesize(); ++i ) cout<<f[i]<<" "; cout<<endl; slide 27
Megoldás class myfstream:public ifstream{ public: myfstream( const char * fname ):ifstream(fname){ char operator[]( int index ){ this->seekg(index); return this->get(); ; long filesize(){ this->seekg(0, ios::end); streampos size = this->tellg(); this->seekg(0, ios::beg); return size; slide 28
Általánosítás IndexFileStream f("be.txt"); for( int i=0; i<f.filesize(); ++i ) cout<<f[i]<<" "; cout<<endl; for( int i=0; i<f.filesize(); ++i ) f[i]=::toupper( f[i] ); cout<<endl; for( int i=0; i<f.filesize(); ++i ) cout<<f[i]<<" "; cout<<endl; slide 29
Megoldás köztes osztály (1) class Position{ fstream& stream; long pos; public: Position( fstream& stream, long pos ): stream(stream), pos( pos){ Position& operator=( const char c ){//Fájlba ír stream.seekp( pos, ios::beg ); stream.put( c ); return *this; operator char(){ //Fájlból olvas stream.seekg( pos, ios::beg ); return stream.get( ); ; slide 30
Megoldás (2) class IndexFileStream: public fstream{ public: IndexFileStream( const char * fname ):fstream(fname){ ; Position operator[]( int index ){ this->seekg(index, ios::beg); return Position( *this, index); long filesize(){ this->seekg(0, ios::end); streampos size = this->tellg(); this->seekg(0, ios::beg); return size; slide 31