Essential C++ 第五章程式碼
阿新 • • 發佈:2019-01-05
版本一(5.1~5.6內容)
#include <iostream> #include <vector> using namespace std; class num_sequence{ public: virtual ~num_sequence() {}; virtual int elem(int pos) const = 0; virtual const char* what_am_i() const = 0; static int max_elem() { return _max_elems;} virtual ostream& print(ostream &os = cout ) const = 0; protected: virtual void gen_elems(int pos) const = 0; bool check_integrity(int pos, int size) const; const static int _max_elems = 25; }; bool num_sequence::check_integrity(int pos,int size) const { if (pos <= 0 || pos >= _max_elems) { cerr << "!! invalid position: " << pos << " Cannot honor request.\n"; return false; } if (pos > size) gen_elems(pos); return true; } ostream& operator<<( ostream &os, const num_sequence &ns) { return ns.print( os); } class Fibonacci:public num_sequence{ public: Fibonacci( int len = 1, int beg_pos = 1) : _length(len), _beg_pos(beg_pos) {} virtual int elem(int pos) const; virtual const char* what_am_i() const { return "Fibonacci";} virtual ostream& print( ostream &os = cout) const; int length() const { return _length;} int beg_pos() const { return _beg_pos;} protected: virtual void gen_elems(int pos) const; int _length; int _beg_pos; static vector<int> _elems; }; vector<int> Fibonacci::_elems; int Fibonacci::elem(int pos) const { if (! check_integrity(pos,_elems.size())) return 0; return _elems[pos-1]; } void Fibonacci::gen_elems(int pos) const { if (_elems.empty()) { _elems.push_back(1); cout << "gen_elems: 1\n"; _elems.push_back(1); cout << "gen_elems: 1\n"; } if (_elems.size() <= (unsigned)pos) { int ix = _elems.size(); int n_2 = _elems[ix-2]; int n_1 = _elems[ix-1]; for(; ix < pos; ++ix) { int elem = n_2 + n_1; cout << "gen_elems: " <<elem << endl; _elems.push_back(elem); n_2 = n_1; n_1 = elem; } } } ostream& Fibonacci::print(ostream &os) const { int elem_pos = _beg_pos - 1; int end_pos = elem_pos + _length; if ( (unsigned)end_pos > _elems.size() ) Fibonacci::gen_elems(end_pos); while (elem_pos < end_pos) os << _elems[elem_pos++] << ' '; return os; } class Triangular:public num_sequence{ public: Triangular( int len = 1, int beg_pos = 1) : _length(len), _beg_pos(beg_pos) {} virtual int elem(int pos) const; virtual const char* what_am_i() const { return "Triangular";} virtual ostream& print( ostream &os = cout) const; int length() const { return _length;} int beg_pos() const { return _beg_pos;} protected: virtual void gen_elems(int pos) const; int _length; int _beg_pos; static vector<int> _elems; }; vector<int> Triangular::_elems; int Triangular::elem(int pos) const { if (! check_integrity(pos,_elems.size())) return 0; return _elems[pos-1]; } void Triangular::gen_elems(int pos) const { if (_elems.size() <= (unsigned)pos) { int ix = _elems.size() ? _elems.size()+1 : 1; for( ; ix <= pos; ++ix) { _elems.push_back(ix*(ix+1)/2); cout << "gen_elems: " << *(--_elems.end()) << endl; } } } ostream& Triangular::print(ostream &os) const { int elem_pos = _beg_pos - 1; int end_pos = elem_pos + _length; if ( (unsigned)end_pos > _elems.size() ) Triangular::gen_elems(end_pos); while (elem_pos < end_pos) os << _elems[elem_pos++] << ' '; return os; } inline void display(const num_sequence &ns, int pos, ostream &os = cout) { os << "The element at position " << pos << " for the " << ns.what_am_i() << " sequence is " << ns.elem(pos) << endl; } int main() { Fibonacci fib; cout << fib << endl << endl; Fibonacci fib2(6); cout << fib2 << endl << endl; Fibonacci fib3(5,8); cout << fib3 << endl; cout << fib3.elem(20) << endl; Triangular tri(2,5); cout << tri << endl; display(tri,20); }
版本二(5.7~5.10)
#include <iostream> #include <vector> #include <typeinfo> using namespace std; class num_sequence{ public: virtual ~num_sequence() {}; // virtual const char* what_am_i() const = 0; int elem(int pos) const; int length() const { return _length;} int beg_pos() const { return _beg_pos;} static int max_elem() { return _max_elems;} ostream& print(ostream &os = cout ) const; inline const char* what_am_i() const { return typeid(*this).name();} protected: // virtual void gen_elems(int pos) const = 0; bool check_integrity(int pos, int size) const; virtual void gen_elems(int pos) const = 0; const static int _max_elems = 25; num_sequence(int len, int bp, vector<int> &re ) : _length(len), _beg_pos(bp), _relems(re) {} int _length; int _beg_pos; vector<int> &_relems; }; bool num_sequence::check_integrity(int pos,int size) const { if (pos <= 0 || pos >= _max_elems) { cerr << "!! invalid position: " << pos << " Cannot honor request.\n"; return false; } if (pos > size) gen_elems(pos); return true; } int num_sequence::elem(int pos) const { if (! check_integrity(pos,_relems.size())) return 0; return _relems[pos-1]; } ostream& num_sequence::print(ostream &os) const { int elem_pos = _beg_pos - 1; int end_pos = elem_pos + _length; if ( (unsigned)end_pos > _relems.size() ) gen_elems(end_pos); os << what_am_i() << " (" << length() << "," << beg_pos() << "): " ; while (elem_pos < end_pos) os << _relems[elem_pos++] << ' '; return os; } class Fibonacci:public num_sequence{ public: Fibonacci( int len = 1, int beg_pos = 1) : num_sequence(len, beg_pos, _elems) {} // virtual const char* what_am_i() const { return "Fibonacci";} protected: virtual void gen_elems(int pos) const; static vector<int> _elems; }; vector<int> Fibonacci::_elems; void Fibonacci::gen_elems(int pos) const { if (_elems.empty()) { _elems.push_back(1); // cout << "gen_elems: 1\n"; _elems.push_back(1); // cout << "gen_elems: 1\n"; } if (_elems.size() <= (unsigned)pos) { int ix = _elems.size(); int n_2 = _elems[ix-2]; int n_1 = _elems[ix-1]; for(; ix < pos; ++ix) { int elem = n_2 + n_1; // cout << "gen_elems: " <<elem << endl; _elems.push_back(elem); n_2 = n_1; n_1 = elem; } } } class Triangular:public num_sequence{ public: Triangular( int len = 1, int beg_pos = 1) : num_sequence(len, beg_pos, _elems) {} // virtual const char* what_am_i() const { return "Triangular";} protected: virtual void gen_elems(int pos) const; static vector<int> _elems; }; vector<int> Triangular::_elems; void Triangular::gen_elems(int pos) const { if (_elems.size() <= (unsigned)pos) { int ix = _elems.size() ? _elems.size()+1 : 1; for( ; ix <= pos; ++ix) { _elems.push_back(ix*(ix+1)/2); // cout << "gen_elems: " << *(--_elems.end()) << endl; } } } ostream& operator<<( ostream &os, const num_sequence &ns) { return ns.print( os); } inline void display(const num_sequence &ns, int pos, ostream &os = cout) { os << "The element at position " << pos << " for the " << ns.what_am_i() << " sequence is " << ns.elem(pos) << endl; } int main() { Fibonacci fib; cout << fib << endl; Fibonacci fib2(6); cout << fib2 << endl; Fibonacci fib3(5,8); cout << fib3 << endl; Fibonacci fib4(fib3); Fibonacci fib5 = fib4; cout << fib5 << endl; Triangular tri(2,5); cout << tri << endl; display(tri,20); }
版本二中,return typeid(*this).name(),會分別返回"9Fibonacci","10Triangular",前面的數字表示的是後面字串的長度....怎麼去掉..不知.....