num_sequence.h
#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_elems() { return _max_elems; } // 括号后面不加分号
virtual ostream& print( ostream &os = cout ) const = 0; ///////////
//virtual const char* test(){ return "num_seq test"; }
protected:
virtual void gen_elems( int pos ) const = 0;
bool check_integrity( int pos, int size) const;
const static int _max_elems = 1024; // 前面加 const
};
class Fibonacci : public num_sequence
{
public:
Fibonacci( int len = 1, int beg = 1 )
: _len( len ), _beg_pos( beg ){}
int elem( int pos) const;
virtual const char *what_am_i() const { return "Fibonacci"; }
ostream& print( ostream &os = cout ) const;
int length(){ return _len; }
int beg_pos(){ return _beg_pos; }
//const char* test(){ return "fib_seq test"; }
protected:
void gen_elems( int pos ) const;
private:
int _len;
int _beg_pos;
static vector<int> _elems;
}; // 类后面要加分号
//vector<int> Fibonacci::_elems; // 在此处定义_elems
//也可以,或者在main.cc,不然会报_elems 未定义错误
// operator<<
ostream& operator<<( ostream &os, const num_sequence &ns)
{
return ns.print(os);
}
// check_integrity //此处的check_integrity 只是大致判断了范围,不具体不确切
#if 0
inline bool num_sequence::check_integrity ( int pos ) const
{
if (pos <= 0 || pos > _max_elems)
{
cerr << "invailed position" << pos <<endl;
return false;
}
return true;
}
#endif
#if 0
// 更具体的 检查完整性方式,但不完美,check_integrity在基类中并不是virtual
// 因此通过指向基类的指针或引用时会出现只调用基类的check_integrity
// 若采取在基类中定义该函数为virtual,同样也是不完美的,因为根据不完整信息所实现的内容,
// 可能也是不完整的,这和型别相依相悖
inline bool Fibonacci::
check_integrity ( int pos ) const
{
if (! num_sequence::check_integrity(pos)) //必须加上类运算符,不然就是Fib
return false;
if (pos > _elems.size())
Fibonacci::gen_elems(pos);
return true;
}
#else
// 因此重写 check_integrity,属于 num_sequence类,
// 采取两个参数
inline bool num_sequence::
check_integrity(int pos, int size) const
{
if (pos <= 0 || pos > _max_elems)
{
cerr << "invailed position" << pos <<endl;
return false;
}
if (pos > size)
gen_elems(pos); // 通过虚拟机制调用,结合了gen,因此print 和 elem函数就可以去掉 gen_elems
return true;
}
#endif
#if 1
//ostream& Fibonacci::print( ostream &os = cout ) const //此处错误
ostream& Fibonacci::
print( ostream &os) const
{
unsigned int elem_pos = _beg_pos - 1; //_beg_pos = 1 initialize
unsigned int end_pos = elem_pos + _len;
if (end_pos > _elems.size())
Fibonacci::gen_elems(end_pos); // 此处加::作用域 编译期而不用等到执行期
while (elem_pos < end_pos)
os << _elems[elem_pos++] << ' ';
return os;
}
#else
ostream& Fibonacci::
print( ostream &os) const
{
unsigned int elem_pos = _beg_pos - 1; //_beg_pos = 1 initialize
unsigned int end_pos = elem_pos + _len;
if (!check_integrity(end_pos, _elems.size()))
// 此处不知道返回什么
while (elem_pos < end_pos)
os << _elems[elem_pos++] << ' ';
return os;
}
#endif
#if 0
int Fibonacci::elem( int pos ) const
{
if ( !check_integrity(pos) )
return 0;
if ( (unsigned int)pos > _elems.size()) // 放到了 check_integrity中,相当于每个派生类都不用再写这段添加代码
{
Fibonacci::gen_elems(pos);
}
return _elems[pos - 1];
}
#else
int Fibonacci::elem( int pos ) const
{
if ( !check_integrity(pos, _elems.size()) )
return 0;
return _elems[pos - 1];
}
#endif
void Fibonacci::gen_elems( int pos ) const
{
if ( _elems.empty() )
{
_elems.push_back(1);
_elems.push_back(1);
}
if ( _elems.size() <= (unsigned int)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;
_elems.push_back(elem);
n_2 = n_1; n_1 = elem;
}
}
}
main.cc
#include "num_sequence.h"
vector<int> Fibonacci::_elems;
int main()
{
//num_sequence *ps = new Fibonacci; // 派生类定义了该虚拟函数,才可以定义基类对象,通过派生类定义
//num_sequence *ps2 = new Fibonacci( 2, 2);
cout << "init main.\n";
Fibonacci fib;
cout << "fib: beginning at element 1 for 1 element: "
<< fib << endl; // fib 由于重载了 operator<< 运算发,并且调用print函数
Fibonacci fib2(10);
cout << "fib: beginning at element 1 for 10 element: "
<< fib2 << endl; // fib 由于重载了 operator<< 运算发,并且调用print函数
Fibonacci fib3(3, 8); // len = 3, _beg_pos = 7
cout << "fib: beginning at element 7 for 3 element: "
<< fib3 << endl; // fib 由于重载了 operator<< 运算发,并且调用print函数
return 0;
}