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