BUFFER.H
上传用户:zengbais
上传日期:2022-08-08
资源大小:49k
文件大小:8k
开发平台:

C++ Builder

  1. #ifndef BUFFER_H
  2. #define BUFFER_H
  3. // 功能:定义数据缓冲区各抽象类
  4. #ifndef DOUBLE
  5. #define DOUBLE double
  6. // #define DOUBLE long double  // 如double精度不够,则可将此行去注释,而将上行注释
  7. // 即可得到更精确的结果
  8. #endif // DOUBLE
  9. #include <stdio.h>
  10. extern DOUBLE defaulterr; // 缺省的误差标准,为十的负八次方
  11. extern int doadjust; // 逻辑变量,为1则作调整,否则不作,缺省为1
  12. DOUBLE adjust(DOUBLE & a);  // 将实数调整为最靠近的小数点后二位数
  13. class buffer {  // 定义抽象的双精度实数缓冲区类,此类以一维数组的形式专门存储大量的
  14. // 双精度实数,而存储方式则由子类实现,即可以用内存,也可以用磁盘
  15. // 空间,甚至服务器上的存储空间
  16.  public:
  17. size_t refnum; // 引用数,一个缓冲区可能有多个矩阵同时引用它,
  18. // 主要是在矩阵变量赋值导致多个矩阵具有同样的内容时
  19. // 防止数据的大量拷贝,而引用数就说明现在有多少个
  20. // 矩阵正在引用这个缓冲区
  21. buffer():refnum(1){}; // 构造函数,预设引用数为1
  22. virtual void alloc(size_t num)=0;  // 申请容量为num的存储空间,或将缓冲区容量
  23. //改为num,纯虚函数,子类必须实现
  24. virtual void release()=0; // 释放占用的存储空间
  25. virtual DOUBLE& retrieve(size_t n)=0;  // 取出第n个双精度实型数据,n从0开始计算
  26. virtual buffer* clone()=0; // 克隆出一个和自己类别一样,内容也一样的新的缓冲区,
  27. // 为纯虚函数,子类必须实现
  28. virtual buffer* newbuf(size_t n=0)=0; // 产生一个新的和自己类别一样的具有指定
  29. // 尺寸的缓冲区,
  30. DOUBLE & operator[](size_t n){ // 重载数组操作符(), 检索第n个字节的内容
  31. return retrieve(n);};
  32. virtual size_t len()=0; // 返回数组的长度,纯虚函数,必须由子类
  33. // 实现
  34. buffer* set(size_t n, DOUBLE d);
  35. // 将实数缓冲区的第n个实数的值设为d,并返回一个实数缓冲区的
  36. // 指针,此指针一般就是指向自己,而在一个缓冲区的引用数多于一个时
  37. // 此函数将先克隆出一个新的缓冲区,此新的缓冲区的引用数为1,并对此
  38. // 新的缓冲区的第n个实数的值设为d,然后返加新缓冲区的指针
  39. friend ostream& operator<<(ostream& o, buffer& b);
  40. };
  41. ostream& operator<<(ostream& o, buffer& b);
  42. buffer * getnewbuffer(size_t n=0);  // 生成一个新的尺寸为n个实数的缓冲区,返回新产生的
  43. // 缓冲区的指针,新产生的缓冲区的类别与下面的
  44. // defbuffer指针指向的缓冲区的类别一致
  45. extern buffer *defbuffer; // 指向buffer子类的变量,作为产生新的缓冲区的缺省类别
  46. void settomemory(); // 将defbuffer指向内存类,这以后再调用getnewbuffer将产生内存类的
  47. // 实数数组,即数组全部放在内存中
  48. void settodisk(); // 将defbuffer指向磁盘类,这以后再调用getnewbuffer将产生数据存放在文件
  49. // 中的实数数组,即数组全部放在数据文件中
  50. class membuffer : public buffer { // 一维的存放在内存中的双精度实数数组,请注意在DOS
  51. // 操作系统下将受到64k内存段容量限制,而如果在win95以上
  52. // 操作系统中用32位编译则没有这个限制。如果要在DOS下使用
  53. // 扩展内存或扩充内存,可以另外编写buffer的子类
  54.  public:
  55. DOUBLE * buf; // 指向存放双精度实数数据的内存缓冲区的指针
  56. size_t length; // 数组的以实数个数计的长度
  57. membuffer():buffer(),buf(0),length(0){}; // 构造函数,产生一个容量为0的实数缓冲区
  58. membuffer(size_t lth):buffer(),length(lth){ // 构造函数,产生长度为lth的实数缓冲区
  59. if(lth > 0)
  60. buf = new DOUBLE[lth];
  61. else buf = 0; };
  62. ~membuffer(){delete buf;}  // 析构函数,释放缓冲区
  63. void alloc(size_t num){  // 将缓冲区的容量改为num个实数,原来的内容全部删去
  64. delete []buf;
  65. length = num;
  66. buf = new DOUBLE[num]; };
  67. DOUBLE& retrieve(size_t n){ // 返回第n个字节,n的范围从0到length-1
  68. return buf[n]; };
  69. void release() { delete []buf; length = 0; };  // 释放内存,数组的长度变为0
  70. buffer* clone(); // 克隆自己
  71. buffer* newbuf(size_t n=0){ // 产生一个长度为n的与自己同类别的新缓冲区并返回
  72. // 相应的指针
  73. return new membuffer(n);};
  74. size_t len(){return length;}; // 返回数组的长度
  75. };
  76. class diskbuffer : public buffer { // 磁盘实数缓冲区类,将实数数组存放在临时文件中
  77.  public:
  78. DOUBLE buf; // 临时文件取出来的实数放在buf里
  79. size_t length; // 缓冲区的长度,或者实数的个数
  80. size_t n; // 当前的buf中存放的是第n个实数,也以此知道临时文件的当前指针位置
  81. FILE * tempfp;    // 指向临时文件的指针
  82. diskbuffer():buffer(),buf(0.0),length(0),tempfp(0),n(0){}; // 缺省构造函数,产生长度为0的
  83. // 磁盘实数缓冲区
  84. diskbuffer(size_t lth); // 构造函数,产生长度为lth的磁盘实数缓冲区
  85. ~diskbuffer(); // 析构函数,关闭并删除临时文件
  86. void alloc(size_t num); // 将缓冲区的尺寸重定为num
  87. DOUBLE& retrieve(size_t n); // 检索出文件的第n个实数放在buf中并返回buf的引用
  88. // 在检索之前先把当前的buf中的内容放回到文件中
  89. void release(); // 释放空间
  90. buffer* clone(); // 克隆自己
  91. buffer* newbuf(size_t n=0){return new diskbuffer(n);}; // 产生一个新的磁盘实数缓冲区
  92. size_t len(){return length;}; // 获得数组的长度
  93. };
  94. class lbuffer { // 长整数缓冲区的抽象基类,用来存放许多个长整数
  95. // 继承的子类可以使用各种数据载体,如内存或者文件来存放长整数
  96.  public:
  97. size_t refnum; // 缓冲区引用数,原理与buffer的相同
  98. lbuffer():refnum(1){}; // 缺省构造函数
  99. virtual void alloc(size_t num)=0; // 将缓冲区尺寸修改为num,原内容全部删去
  100. virtual void release()=0; // 释放缓冲区
  101. virtual long& retrieve(size_t n)=0; // 检索第n个元素,并返回引用
  102. long & operator[](size_t n){ // 重载[]操作符,得到第n个元素,并返回引用
  103. // 但这样调用有危险,要注意引用数为1时才可当左值
  104. return retrieve(n);};
  105. virtual lbuffer* clone()=0; // 克隆一个类别和内容与自己完全一样的长整数缓冲区
  106. virtual lbuffer* newbuf(size_t n=0)=0; // 产生一个类别和自己一样的长整数缓冲区
  107. virtual size_t len()=0; // 返回长度
  108. lbuffer* set(size_t n, long v); // 设置第n个元素的值为v,n的范围是0到refnum-1
  109. // 如引用数大于1,则会产生新的缓冲区进行操作
  110. // 并返回新缓冲区指针
  111. friend ostream& operator<<(ostream& o, lbuffer& b);
  112. };
  113. ostream& operator<<(ostream& o, lbuffer& b);
  114. class lmembuffer : public lbuffer { // 内存长整数缓冲区,DOS系统将受到64K段限制
  115.  public:
  116. long * buf; // 指向内存缓冲区的指针
  117. size_t length; // 缓冲区长度
  118. lmembuffer():lbuffer(),buf(0),length(0){}; // 缺省构造函数,长度为0
  119. lmembuffer(size_t lth):lbuffer(),length(lth){ // 构造函数,lth为缓冲区长整数个数
  120. buf = new long[lth]; };
  121. ~lmembuffer(){delete []buf;} // 析构函数,释放buf指向的内存
  122. void alloc(size_t num){ // 将缓冲区长度修改为num,原内容消失
  123. delete []buf;
  124. length = num;
  125. buf = new long[num]; };
  126. long& retrieve(size_t n){ // 返回第n个长整数,n取值从0到length-1
  127. return buf[n]; };
  128. void release() { delete []buf; length = 0; }; // 释放内存,长度变为0
  129. lbuffer* clone(); // 克隆一个内容完全一样的长整数缓冲区
  130. lbuffer* newbuf(size_t n=0){return new lmembuffer(n);}; // 产生一个新的尺寸为n的缓冲区
  131. size_t len(){return length;}; // 返回缓冲区的长度
  132. };
  133. class ldiskbuffer : public lbuffer { // 长整数磁盘缓冲区子类,将多个长整数存放在临时文件内
  134.  public:
  135. long buf; // 当前的长整数
  136. size_t length; // 缓冲区长度,以长整数个数为单位
  137. size_t n; // buf中的内容是第n个元素的内容,n也说明了临时文件当前的指向
  138. FILE * tempfp; // 临时文件指针
  139. ldiskbuffer():lbuffer(),buf(0),length(0),tempfp(0),n(0){}; // 缺省构造函数,长度为0
  140. ldiskbuffer(size_t lth); // 构造函数,lth为缓冲区长度
  141. ~ldiskbuffer(); // 析构函数,将关闭和删除临时文件
  142. void alloc(size_t num); // 将缓冲区长度重新定为num
  143. long& retrieve(size_t nn); // 检索第nn个元素放到buf中,在此之前先存放buf的内容到
  144. // n的位置,再将文件的指针移到nn处取元素
  145. void release(); // 释放存储空间
  146. lbuffer* clone(); // 克隆一个内容完全一样的长整数磁盘缓冲区,但临时文件不同
  147. lbuffer* newbuf(size_t nn=0){return new ldiskbuffer(nn);}; // 产生一个长度为nn的
  148. // 长整数磁盘缓冲区子类变量,返回它的指针
  149. size_t len(){return length;}; // 返回缓冲区长度
  150. };
  151. lbuffer * getnewlbuffer(size_t n=0); // 产生一个新的长整数缓冲区,子类的类别与下面的
  152. // deflbuffer指向的缓冲区的类别相同
  153. extern lbuffer *deflbuffer; // 缺省的长整数缓冲区指针
  154. char * throwmessage(int l, char * f, char * c); // 产生错误信息字符串
  155. #ifndef __LINE__
  156. #define __LINE__ 0
  157. #define __FILE__ "n"
  158. #endif
  159. //  l为行号,f为文件名,c为出错信息,请不要直接调用,而是调用宏TMESSAGE
  160. #define TMESSAGE(c) throwmessage(__LINE__,__FILE__,c)
  161. #endif // BUFFER_H