?? buffer.h
字號:
#ifndef BUFFER_H
#define BUFFER_H
// 功能:定義數據緩沖區各抽象類
#ifndef DOUBLE
#define DOUBLE double
// #define DOUBLE long double // 如double精度不夠,則可將此行去注釋,而將上行注釋
// 即可得到更精確的結果
#endif // DOUBLE
#include <stdio.h>
extern DOUBLE defaulterr; // 缺省的誤差標準,為十的負八次方
extern int doadjust; // 邏輯變量,為1則作調整,否則不作,缺省為1
DOUBLE adjust(DOUBLE & a); // 將實數調整為最靠近的小數點后二位數
class buffer { // 定義抽象的雙精度實數緩沖區類,此類以一維數組的形式專門存儲大量的
// 雙精度實數,而存儲方式則由子類實現,即可以用內存,也可以用磁盤
// 空間,甚至服務器上的存儲空間
public:
size_t refnum; // 引用數,一個緩沖區可能有多個矩陣同時引用它,
// 主要是在矩陣變量賦值導致多個矩陣具有同樣的內容時
// 防止數據的大量拷貝,而引用數就說明現在有多少個
// 矩陣正在引用這個緩沖區
buffer():refnum(1){}; // 構造函數,預設引用數為1
virtual void alloc(size_t num)=0; // 申請容量為num的存儲空間,或將緩沖區容量
//改為num,純虛函數,子類必須實現
virtual void release()=0; // 釋放占用的存儲空間
virtual DOUBLE& retrieve(size_t n)=0; // 取出第n個雙精度實型數據,n從0開始計算
virtual buffer* clone()=0; // 克隆出一個和自己類別一樣,內容也一樣的新的緩沖區,
// 為純虛函數,子類必須實現
virtual buffer* newbuf(size_t n=0)=0; // 產生一個新的和自己類別一樣的具有指定
// 尺寸的緩沖區,
DOUBLE & operator[](size_t n){ // 重載數組操作符(), 檢索第n個字節的內容
return retrieve(n);};
virtual size_t len()=0; // 返回數組的長度,純虛函數,必須由子類
// 實現
buffer* set(size_t n, DOUBLE d);
// 將實數緩沖區的第n個實數的值設為d,并返回一個實數緩沖區的
// 指針,此指針一般就是指向自己,而在一個緩沖區的引用數多于一個時
// 此函數將先克隆出一個新的緩沖區,此新的緩沖區的引用數為1,并對此
// 新的緩沖區的第n個實數的值設為d,然后返加新緩沖區的指針
friend ostream& operator<<(ostream& o, buffer& b);
};
ostream& operator<<(ostream& o, buffer& b);
buffer * getnewbuffer(size_t n=0); // 生成一個新的尺寸為n個實數的緩沖區,返回新產生的
// 緩沖區的指針,新產生的緩沖區的類別與下面的
// defbuffer指針指向的緩沖區的類別一致
extern buffer *defbuffer; // 指向buffer子類的變量,作為產生新的緩沖區的缺省類別
void settomemory(); // 將defbuffer指向內存類,這以后再調用getnewbuffer將產生內存類的
// 實數數組,即數組全部放在內存中
void settodisk(); // 將defbuffer指向磁盤類,這以后再調用getnewbuffer將產生數據存放在文件
// 中的實數數組,即數組全部放在數據文件中
class membuffer : public buffer { // 一維的存放在內存中的雙精度實數數組,請注意在DOS
// 操作系統下將受到64k內存段容量限制,而如果在win95以上
// 操作系統中用32位編譯則沒有這個限制。如果要在DOS下使用
// 擴展內存或擴充內存,可以另外編寫buffer的子類
public:
DOUBLE * buf; // 指向存放雙精度實數數據的內存緩沖區的指針
size_t length; // 數組的以實數個數計的長度
membuffer():buffer(),buf(0),length(0){}; // 構造函數,產生一個容量為0的實數緩沖區
membuffer(size_t lth):buffer(),length(lth){ // 構造函數,產生長度為lth的實數緩沖區
if(lth > 0)
buf = new DOUBLE[lth];
else buf = 0; };
~membuffer(){delete buf;} // 析構函數,釋放緩沖區
void alloc(size_t num){ // 將緩沖區的容量改為num個實數,原來的內容全部刪去
delete []buf;
length = num;
buf = new DOUBLE[num]; };
DOUBLE& retrieve(size_t n){ // 返回第n個字節,n的范圍從0到length-1
return buf[n]; };
void release() { delete []buf; length = 0; }; // 釋放內存,數組的長度變為0
buffer* clone(); // 克隆自己
buffer* newbuf(size_t n=0){ // 產生一個長度為n的與自己同類別的新緩沖區并返回
// 相應的指針
return new membuffer(n);};
size_t len(){return length;}; // 返回數組的長度
};
class diskbuffer : public buffer { // 磁盤實數緩沖區類,將實數數組存放在臨時文件中
public:
DOUBLE buf; // 臨時文件取出來的實數放在buf里
size_t length; // 緩沖區的長度,或者實數的個數
size_t n; // 當前的buf中存放的是第n個實數,也以此知道臨時文件的當前指針位置
FILE * tempfp; // 指向臨時文件的指針
diskbuffer():buffer(),buf(0.0),length(0),tempfp(0),n(0){}; // 缺省構造函數,產生長度為0的
// 磁盤實數緩沖區
diskbuffer(size_t lth); // 構造函數,產生長度為lth的磁盤實數緩沖區
~diskbuffer(); // 析構函數,關閉并刪除臨時文件
void alloc(size_t num); // 將緩沖區的尺寸重定為num
DOUBLE& retrieve(size_t n); // 檢索出文件的第n個實數放在buf中并返回buf的引用
// 在檢索之前先把當前的buf中的內容放回到文件中
void release(); // 釋放空間
buffer* clone(); // 克隆自己
buffer* newbuf(size_t n=0){return new diskbuffer(n);}; // 產生一個新的磁盤實數緩沖區
size_t len(){return length;}; // 獲得數組的長度
};
class lbuffer { // 長整數緩沖區的抽象基類,用來存放許多個長整數
// 繼承的子類可以使用各種數據載體,如內存或者文件來存放長整數
public:
size_t refnum; // 緩沖區引用數,原理與buffer的相同
lbuffer():refnum(1){}; // 缺省構造函數
virtual void alloc(size_t num)=0; // 將緩沖區尺寸修改為num,原內容全部刪去
virtual void release()=0; // 釋放緩沖區
virtual long& retrieve(size_t n)=0; // 檢索第n個元素,并返回引用
long & operator[](size_t n){ // 重載[]操作符,得到第n個元素,并返回引用
// 但這樣調用有危險,要注意引用數為1時才可當左值
return retrieve(n);};
virtual lbuffer* clone()=0; // 克隆一個類別和內容與自己完全一樣的長整數緩沖區
virtual lbuffer* newbuf(size_t n=0)=0; // 產生一個類別和自己一樣的長整數緩沖區
virtual size_t len()=0; // 返回長度
lbuffer* set(size_t n, long v); // 設置第n個元素的值為v,n的范圍是0到refnum-1
// 如引用數大于1,則會產生新的緩沖區進行操作
// 并返回新緩沖區指針
friend ostream& operator<<(ostream& o, lbuffer& b);
};
ostream& operator<<(ostream& o, lbuffer& b);
class lmembuffer : public lbuffer { // 內存長整數緩沖區,DOS系統將受到64K段限制
public:
long * buf; // 指向內存緩沖區的指針
size_t length; // 緩沖區長度
lmembuffer():lbuffer(),buf(0),length(0){}; // 缺省構造函數,長度為0
lmembuffer(size_t lth):lbuffer(),length(lth){ // 構造函數,lth為緩沖區長整數個數
buf = new long[lth]; };
~lmembuffer(){delete []buf;} // 析構函數,釋放buf指向的內存
void alloc(size_t num){ // 將緩沖區長度修改為num,原內容消失
delete []buf;
length = num;
buf = new long[num]; };
long& retrieve(size_t n){ // 返回第n個長整數,n取值從0到length-1
return buf[n]; };
void release() { delete []buf; length = 0; }; // 釋放內存,長度變為0
lbuffer* clone(); // 克隆一個內容完全一樣的長整數緩沖區
lbuffer* newbuf(size_t n=0){return new lmembuffer(n);}; // 產生一個新的尺寸為n的緩沖區
size_t len(){return length;}; // 返回緩沖區的長度
};
class ldiskbuffer : public lbuffer { // 長整數磁盤緩沖區子類,將多個長整數存放在臨時文件內
public:
long buf; // 當前的長整數
size_t length; // 緩沖區長度,以長整數個數為單位
size_t n; // buf中的內容是第n個元素的內容,n也說明了臨時文件當前的指向
FILE * tempfp; // 臨時文件指針
ldiskbuffer():lbuffer(),buf(0),length(0),tempfp(0),n(0){}; // 缺省構造函數,長度為0
ldiskbuffer(size_t lth); // 構造函數,lth為緩沖區長度
~ldiskbuffer(); // 析構函數,將關閉和刪除臨時文件
void alloc(size_t num); // 將緩沖區長度重新定為num
long& retrieve(size_t nn); // 檢索第nn個元素放到buf中,在此之前先存放buf的內容到
// n的位置,再將文件的指針移到nn處取元素
void release(); // 釋放存儲空間
lbuffer* clone(); // 克隆一個內容完全一樣的長整數磁盤緩沖區,但臨時文件不同
lbuffer* newbuf(size_t nn=0){return new ldiskbuffer(nn);}; // 產生一個長度為nn的
// 長整數磁盤緩沖區子類變量,返回它的指針
size_t len(){return length;}; // 返回緩沖區長度
};
lbuffer * getnewlbuffer(size_t n=0); // 產生一個新的長整數緩沖區,子類的類別與下面的
// deflbuffer指向的緩沖區的類別相同
extern lbuffer *deflbuffer; // 缺省的長整數緩沖區指針
char * throwmessage(int l, char * f, char * c); // 產生錯誤信息字符串
#ifndef __LINE__
#define __LINE__ 0
#define __FILE__ "n"
#endif
// l為行號,f為文件名,c為出錯信息,請不要直接調用,而是調用宏TMESSAGE
#define TMESSAGE(c) throwmessage(__LINE__,__FILE__,c)
#endif // BUFFER_H
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -