摘要: 外觀模式
前序
這回小菜同學和大鳥討論起了關于股票的事情,小菜提到最近股市很火,不過他的同事一直在虧錢。而大鳥說道:“如果你的同事花錢去投資基金,則不會虧的這么厲害。基金將所有投資者的錢全部集中起來,交由專業的經理人進行管理,投資于股票、債券、外匯等領域。”
而個人進行投資股票,對股票的聯系太多,反而不利于操作,這在軟件中就稱為耦合性過高。而有了基金之后,眾多的用戶只...
閱讀全文
posted @
2011-05-26 17:12 lwch 閱讀(1621) |
評論 (2) |
編輯 收藏
模板方法模式
前序
相信大家已經對上次小菜投遞簡歷的過程已經非常了解了,這回小菜收到了XX公司的面試通知并去完成了面試。回來時大鳥問小菜感覺如何?小菜回答到:“書到用時方恨少呀,英語太爛,沒辦法。”然后兩人討論到以前微軟的MCSE和MCSD認證考試,在剛開始時有很多教育機構弄到了題庫,并承諾保證通過,不通過不收費。于是小菜的一位同學并不是計算機專業的,靠著背題庫通過了這個世界最大軟件公司的開發技術認證。
最后大鳥說到他小時候因為抄錯題而沒考好,回家父母說他不認真學習。其實問題并不在這里,如果使用標準化的考試卷也就不會產生抄錯題的苦惱。
于是大鳥讓小菜寫了一份抄題的代碼。
小菜的第一份作業
#include <stdio.h>
// 學生甲抄的試卷
class TestPaperA
{
public:
void TestQuestion1()
{
printf("楊過得到,后來給了郭靖,煉成倚天劍、屠龍刀的玄鐵可能是【】a.球磨鑄鐵 b.馬口鐵 c.高速合金鋼 d.碳塑纖維\n");
printf("答案: b\n");
}
void TestQuestion2()
{
printf("楊過、程英、陸無雙鏟除了情花,造成【】a.使這種植物不再害人 b.使一種珍稀物種滅絕 c.破壞了那個生物圈的生態平衡 d.造成該地區沙漠化\n");
printf("答案: a\n");
}
void TestQuestion3()
{
printf("藍鳳凰致使華山師徒、桃谷六神嘔吐不止,如果你是大夫,會給他們開什么藥【】a.阿司匹林 b.牛黃解毒片 c.氟哌酸 d.讓他們喝大量的升牛奶 e.以上全不對\n");
printf("答案: c\n");
}
};
// 學生乙抄的試卷
class TestPaperB
{
public:
void TestQuestion1()
{
printf("楊過得到,后來給了郭靖,煉成倚天劍、屠龍刀的玄鐵可能是【】a.球磨鑄鐵 b.馬口鐵 c.高速合金鋼 d.碳塑纖維\n");
printf("答案: d\n");
}
void TestQuestion2()
{
printf("楊過、程英、陸無雙鏟除了情花,造成【】a.使這種植物不再害人 b.使一種珍稀物種滅絕 c.破壞了那個生物圈的生態平衡 d.造成該地區沙漠化\n");
printf("答案: b\n");
}
void TestQuestion3()
{
printf("藍鳳凰致使華山師徒、桃谷六神嘔吐不止,如果你是大夫,會給他們開什么藥【】a.阿司匹林 b.牛黃解毒片 c.氟哌酸 d.讓他們喝大量的升牛奶 e.以上全不對\n");
printf("答案: a\n");
}
};
int main()
{
printf("學生甲抄的試卷:\n");
TestPaperA studentA;
studentA.TestQuestion1();
studentA.TestQuestion2();
studentA.TestQuestion3();
printf("學生乙抄的試卷:\n");
TestPaperB studentB;
studentB.TestQuestion1();
studentB.TestQuestion2();
studentB.TestQuestion3();
return 0;
}
寫完后小菜說到:“這兩份試卷非常類似,除了答案不同,沒什么不一樣,這樣寫又容易錯,又難以維護。”
“說的對,如果老師突然要改題目,那兩個人就都需要改代碼,如果某人抄錯了,那真是糟糕至極。那你說怎么辦?”
“老師出一份試卷,打印多份,然后讓學生填寫答案就可以了。在這里應該就把尸體和答案分享,抽象出一個父類,讓兩個子類繼承于它,公共的試題代碼寫到父類當中,就可以了。”
模板方法模式
模板方法模式準備一個抽象類,將部分邏輯以具體方法以及具體構造子的形式實現,然后聲明一些抽象方法來迫使子類實現剩余的邏輯。不同的子類可以以不同的方式實現這些抽象方法,從而對剩余的邏輯有不同的實現。先制定一個頂級邏輯框架,而將邏輯的細節留給具體的子類去實現。
實現方法(UML類圖)

實現代碼
#include <stdio.h>
class TestPaper
{
public:
void TestQuestion1()
{
printf("楊過得到,后來給了郭靖,煉成倚天劍、屠龍刀的玄鐵可能是【】a.球磨鑄鐵 b.馬口鐵 c.高速合金鋼 d.碳塑纖維\n");
printf("答案: %c\n",Answer1());
}
void TestQuestion2()
{
printf("楊過、程英、陸無雙鏟除了情花,造成【】a.使這種植物不再害人 b.使一種珍稀物種滅絕 c.破壞了那個生物圈的生態平衡 d.造成該地區沙漠化\n");
printf("答案: %c\n",Answer2());
}
void TestQuestion3()
{
printf("藍鳳凰致使華山師徒、桃谷六神嘔吐不止,如果你是大夫,會給他們開什么藥【】a.阿司匹林 b.牛黃解毒片 c.氟哌酸 d.讓他們喝大量的升牛奶 e.以上全不對\n");
printf("答案: %c\n",Answer3());
}
protected:
virtual char Answer1()=0;
virtual char Answer2()=0;
virtual char Answer3()=0;
};
class TestPaperA : public TestPaper
{
protected:
virtual char Answer1()
{
return 'b';
}
virtual char Answer2()
{
return 'c';
}
virtual char Answer3()
{
return 'a';
}
};
class TestPaperB : public TestPaper
{
protected:
virtual char Answer1()
{
return 'c';
}
virtual char Answer2()
{
return 'a';
}
virtual char Answer3()
{
return 'a';
}
};
int main()
{
printf("學生甲抄的試卷:\n");
TestPaper* studentA = new TestPaperA();
studentA->TestQuestion1();
studentA->TestQuestion2();
studentA->TestQuestion3();
printf("學生乙抄的試卷:\n");
TestPaper* studentB = new TestPaperB();
studentB->TestQuestion1();
studentB->TestQuestion2();
studentB->TestQuestion3();
delete studentA;
delete studentB;
return 0;
}
運行結果
所有文件打包下載
posted @
2011-05-18 14:14 lwch 閱讀(1636) |
評論 (1) |
編輯 收藏
原型模式
前序
這回小菜準備去應聘了,大鳥看了小菜的簡歷后感覺他都是在瞎扯.小菜準備了很多份相同的簡歷.于是大鳥便讓小菜同學通過編寫代碼來實現相同的三份簡歷.
不久后小菜實現了第一版的代碼.
小菜的第一版代碼
#include <stdio.h>
class Resume
{
public:
Resume(char* _name) : name(_name),sex(0),age(0),timeArea(0),company(0){}
void SetPersonalInfo(char* _sex,char* _age)
{
sex = _sex;
age = _age;
}
void SetWorkExperience(char* _timeArea,char* _company)
{
timeArea = _timeArea;
company = _company;
}
void Display()
{
printf("%s %s %s\n",name,sex,age);
printf("工作經歷:%s %s",timeArea,company);
}
protected:
char* name;
char* sex;
char* age;
char* timeArea;
char* company;
};
int main()
{
Resume a("大鳥");
a.SetPersonalInfo("男","29");
a.SetWorkExperience("1998-2000","XX公司");
Resume b("大鳥");
b.SetPersonalInfo("男","29");
b.SetWorkExperience("1998-2000","XX公司");
Resume c("大鳥");
c.SetPersonalInfo("男","29");
c.SetWorkExperience("1998-2000","XX公司");
a.Display();
b.Display();
c.Display();
return 0;
}
大鳥看后說到:”三份簡歷需要三次初始化,這樣客戶端的代碼很麻煩,如果要二十份那就要二十次初始化.”
小菜答到:”是的.如果寫錯了一個字那就要改二十次.”
于是大鳥便叫小菜用原型模式重寫了一遍代碼.
原型模式
通過給出一個原型對象來指明所要創建的對象的類型,然后用復制這個原型對象的方法創建出更多同類型的對象。原始模型模式允許動態的增加或減少產品類,產品類不需要非得有任何事先確定的等級結構,原始模型模式適用于任何的等級結構。缺點是每一個類都必須配備一個克隆方法。
實現方式(UML類圖)

實現代碼
#include <stdio.h>
class ICloneable
{
public:
virtual ICloneable* Clone()=0;
};
// 工作經歷
class WorkExperience : public ICloneable
{
public:
char*& WorkDate()
{
return workDate;
}
char*& Company()
{
return company;
}
virtual WorkExperience* Clone()
{
WorkExperience* Result = new WorkExperience();
Result->WorkDate() = workDate;
Result->Company() = company;
return Result;
}
protected:
char* workDate;
char* company;
};
// 簡歷
class Resume : public ICloneable
{
public:
Resume(char* _name) : name(_name),work(new WorkExperience()){}
~Resume()
{
delete work;
}
void SetPersonalInfo(char* _sex,char* _age)
{
sex = _sex;
age = _age;
}
void SetWorkExperience(char* _workDate,char* _company)
{
work->WorkDate() = _workDate;
work->Company() = _company;
}
void Display()
{
printf("%s %s %s\n",name,sex,age);
printf("工作經歷:%s %s\n",work->WorkDate(),work->Company());
}
virtual Resume* Clone()
{
Resume* Result = new Resume(work);
Result->name = name;
Result->sex = sex;
Result->age = age;
return Result;
}
protected:
Resume(WorkExperience* _work)
{
work = _work->Clone();
}
char* name;
char* sex;
char* age;
WorkExperience* work;
};
int main()
{
Resume* a = new Resume("大鳥");
a->SetPersonalInfo("男","29");
a->SetWorkExperience("1998-2000","XX公司");
Resume* b = a->Clone();
b->SetWorkExperience("1998-2006","YY企業");
Resume* c = a->Clone();
c->SetPersonalInfo("男","24");
c->SetWorkExperience("1998-2003","ZZ企業");
a->Display();
b->Display();
c->Display();
delete a;
delete b;
delete c;
return 0;
}
運行結果

所有文件打包下載
posted @
2011-05-12 16:20 lwch 閱讀(2007) |
評論 (1) |
編輯 收藏
工廠方法模式
前序
小菜同學有個同學叫薛磊風,他做人很低調,經常去勤工儉學.但不巧的是星期天他走在路上被車撞了,并送進了醫院.他在醫院中對小菜和他的同學們說,他經常去幫助以為老奶奶,但是現在他被車撞傷了,沒辦法繼續去幫助那位老奶奶了.應此他希望小菜和其他同學能夠幫助他去照顧那位老奶奶,如果老奶奶問起他們的名字時不要提任何人的名字,說是學雷鋒做好事就行了.
社區志愿者也可以幫助老奶奶,應此幫助老奶奶的對象就可分為(學雷鋒的大學生和社區志愿者),請你用工廠方法模式來設計出幫助老奶奶這件事.
工廠方法模式
核心工廠類不再負責所有產品的創建,而是將具體創建的工作交給子類去做,成為一個抽象工廠角色,僅負責給出具體工廠類必須實現的接口,而不接觸哪一個產品類應當被實例化這種細節。
實現方法(UML類圖)

實現代碼
#include <stdio.h>
// 雷鋒
class LeiFeng
{
public:
void Sweep()
{
printf("掃地\n");
}
void Wash()
{
printf("洗衣\n");
}
void BuyRice()
{
printf("買米\n");
}
};
// 學雷鋒的大學生
class Undergraduate : public LeiFeng
{
public:
};
// 社區志愿者
class Volunterr : public LeiFeng
{
public:
};
// 雷鋒工廠
class IFactory
{
public:
virtual LeiFeng* CreateLeiFeng()=0;
};
// 學雷鋒的大學生工廠
class UndergraduateFactory : public IFactory
{
public:
virtual LeiFeng* CreateLeiFeng()
{
return new Undergraduate();
}
};
// 社區志愿者工廠
class VolunterrFactory : public IFactory
{
public:
virtual LeiFeng* CreateLeiFeng()
{
return new Volunterr();
}
};
int main()
{
IFactory* factory = new UndergraduateFactory();
LeiFeng* student = factory->CreateLeiFeng();
student->BuyRice();
student->Sweep();
student->Wash();
delete factory;
delete student;
return 0;
}
運行結果
買米
掃地
洗衣
所有文件打包下載
posted @
2011-05-10 19:41 lwch 閱讀(1835) |
評論 (0) |
編輯 收藏
代理模式
前序
卓賈易同學為了追求嬌嬌同學,于是要戴勵同學幫他送洋娃娃,花和巧克力給嬌嬌同學.請你用代理模式來設計這些送東西的過程.
代理模式
代理模式給某一個對象提供一個代理對象,并由代理對象控制對源對象的引用。代理就是一個人或一個機構代表另一個人或者一個機構采取行動。某些情況下,客戶不想或者不能夠直接引用一個對象,代理對象可以在客戶和目標對象直接起到中介的作用。客戶端分辨不出代理主題對象與真實主題對象。代理模式可以并不知道真正的被代理對象,而僅僅持有一個被代理對象的接口,這時候代理對象不能夠創建被代理對象,被代理對象必須有系統的其他角色代為創建并傳入。
實現方式(UML類圖)

實現代碼
#include <stdio.h>
class IGiveGift
{
public:
virtual void GiveDolls()=0;
virtual void GiveFlowers()=0;
virtual void GiveChocolate()=0;
};
class SchoolGirl
{
public:
char*& Name()
{
return name;
}
protected:
char* name;
};
class Pursuit : public IGiveGift
{
public:
Pursuit(SchoolGirl* _mm) : mm(_mm){}
virtual void GiveDolls()
{
printf("%s 送你洋娃娃\n",mm->Name());
}
virtual void GiveFlowers()
{
printf("%s 送你鮮花\n",mm->Name());
}
virtual void GiveChocolate()
{
printf("%s 送你巧克力\n",mm->Name());
}
protected:
SchoolGirl* mm;
};
class Proxy : public IGiveGift
{
public:
Proxy(SchoolGirl* mm)
{
gg = new Pursuit(mm);
}
~Proxy()
{
delete gg;
}
virtual void GiveDolls()
{
gg->GiveDolls();
}
virtual void GiveFlowers()
{
gg->GiveFlowers();
}
virtual void GiveChocolate()
{
gg->GiveChocolate();
}
protected:
Pursuit* gg;
};
int main()
{
SchoolGirl* jiaojiao = new SchoolGirl();
jiaojiao->Name() = "李嬌嬌";
Proxy* daili = new Proxy(jiaojiao);
daili->GiveDolls();
daili->GiveFlowers();
daili->GiveChocolate();
delete jiaojiao;
delete daili;
return 0;
}
運行結果

所有文件打包下載
posted @
2011-05-07 23:39 lwch 閱讀(1953) |
評論 (7) |
編輯 收藏
裝飾模式
前序
制作一個可以給人搭配不同的服飾的系統,比如類似QQ,網絡游戲或論壇都有的Avatar系統.
裝飾模式
裝飾模式以對客戶端透明的方式擴展對象的功能,是繼承關系的一個替代方案,提供比繼承更多的靈活性。動態給一個對象增加功能,這些功能可以再動態的撤消。增加由一些基本功能的排列組合而產生的非常大量的功能。
實現方式(UML類圖)

實現代碼
#include <stdio.h>
class Person
{
public:
Person() : name(0){}
Person(char* _name) : name(_name){}
virtual void Show()
{
printf("裝扮的%s",name);
}
protected:
char* name;
};
class Finery : public Person
{
public:
Finery() : component(0){}
void Decorate(Person* component)
{
this->component = component;
}
virtual void Show()
{
if(component) component->Show();
}
protected:
Person* component;
};
class TShirts : public Finery
{
public:
virtual void Show()
{
printf("大T恤 ");
__super::Show();
}
};
class BigTrouser : public Finery
{
public:
virtual void Show()
{
printf("跨褲 ");
__super::Show();
}
};
class Sneakers : public Finery
{
public:
virtual void Show()
{
printf("破球鞋 ");
__super::Show();
}
};
class Suit : public Finery
{
public:
virtual void Show()
{
printf("西裝 ");
__super::Show();
}
};
class Tie : public Finery
{
public:
virtual void Show()
{
printf("領帶 ");
__super::Show();
}
};
class LeatherShoes : public Finery
{
public:
virtual void Show()
{
printf("皮鞋 ");
__super::Show();
}
};
int main()
{
Person* xc = new Person("小菜");
printf("第一種裝扮:\n");
Sneakers* pqx = new Sneakers();
BigTrouser* kk = new BigTrouser();
TShirts* dtx = new TShirts();
pqx->Decorate(xc);
kk->Decorate(pqx);
dtx->Decorate(kk);
dtx->Show();
printf("\n第二種裝扮:\n");
LeatherShoes* px = new LeatherShoes();
Tie* ld = new Tie();
Suit* xz = new Suit();
px->Decorate(xc);
ld->Decorate(px);
xz->Decorate(ld);
xz->Show();
delete xc;
delete pqx;
delete kk;
delete dtx;
delete px;
delete ld;
delete xz;
return 0;
}
運行結果

posted @
2011-05-05 16:04 lwch 閱讀(2635) |
評論 (5) |
編輯 收藏
策略模式
前序
請實現一個商場收銀軟件,包含正常收費,打折收費和返利收費三種具體策略
策略模式
策略模式定義了一系列的算法,并將每一個算法封裝起來,而且使它們還可以相互替換。策略模式讓算法獨立于使用它的客戶而獨立變化。
實現方式(UML類圖)

實現代碼
#include <stdio.h>
class CashSuper
{
public:
virtual double acceptCash(double money)=0;
};
class CashNormal : public CashSuper
{
public:
virtual double acceptCash(double money)
{
return money;
}
};
class CashRebate : public CashSuper
{
protected:
double moneyRebate;
public:
CashRebate() : moneyRebate(1){}
CashRebate(double _moneyRebate) : moneyRebate(_moneyRebate){}
virtual double acceptCash(double money)
{
return money * moneyRebate;
}
};
class CashReturn : public CashSuper
{
protected:
double moneyCondition;
double moneyReturn;
public:
CashReturn() : moneyCondition(0),moneyReturn(0){}
CashReturn(double _moneyCondition,double _moneyReturn)
: moneyCondition(_moneyCondition),moneyReturn(_moneyReturn)
{}
virtual double acceptCash(double money)
{
double result = money;
if(money >= moneyCondition) result -= (int)(money / moneyCondition) * moneyReturn;
return result;
}
};
class CashContext
{
protected:
CashSuper* cs;
public:
CashContext() : cs(0){}
~CashContext()
{
if(cs) delete cs;
}
CashContext& operator=(CashSuper* csuper)
{
if(cs) delete cs;
cs = csuper;
return *this;
}
double GetResult(double money)
{
return cs->acceptCash(money);
}
};
int main()
{
double total = 0;
int Type;
while(1)
{
printf("請輸入收費方式(0~2,-1退出):");
scanf("%d",&Type);
if(Type == -1) break;
CashContext cc;
switch(Type)
{
case 0:
cc = new CashNormal();
break;
case 1:
cc = new CashReturn(300,100);
break;
case 2:
cc = new CashRebate(0.8);
break;
default:
cc = new CashNormal();
break;
}
double Price,Num;
printf("請輸入單價:");
scanf("%lf",&Price);
printf("請輸入數量:");
scanf("%lf",&Num);
total += cc.GetResult(Price * Num);
}
printf("總價:%f\n",total);
return 0;
}
運行結果

所有文件打包下載
posted @
2011-05-04 15:10 lwch 閱讀(1359) |
評論 (0) |
編輯 收藏
簡單工廠模式
前序:
請用一種面向對象的語言來實現一個計算器控制臺程序,要求輸入兩個數和運算符并得到結果
簡單工廠模式:
從設計模式的類型上來說,簡單工廠模式是屬于創建型模式,又叫做靜態工廠方法(StaticFactory Method)模式,但不屬于23種GOF設計模式之一。簡單工廠模式是由一個工廠對象決定創建出哪一種產品類的實例。簡單工廠模式是工廠模式家族中最簡單實用的模式,可以理解為是不同工廠模式的一個特殊實現。
實現方式(UML類圖):

實現代碼:
#include <stdio.h>
class Operation
{
public:
double NumberA;
double NumberB;
virtual double GetResult()
{
return 0;
}
};
class OperationAdd : public Operation
{
public:
virtual double GetResult()
{
return NumberA + NumberB;
}
};
class OperationSub : public Operation
{
public:
virtual double GetResult()
{
return NumberA - NumberB;
}
};
class OperationMul : public Operation
{
public:
virtual double GetResult()
{
return NumberA * NumberB;
}
};
class OperationDiv : public Operation
{
public:
virtual double GetResult()
{
if(NumberB == 0) return 0;
return NumberA / NumberB;
}
};
class OperationFactory
{
public:
static Operation* createOperate(char operate)
{
Operation* oper = 0;
switch(operate)
{
case '+':
oper = new OperationAdd();
break;
case '-':
oper = new OperationSub();
break;
case '*':
oper = new OperationMul();
break;
case '/':
oper = new OperationDiv();
break;
}
return oper;
}
};
int main()
{
Operation* oper = OperationFactory::createOperate('+');
oper->NumberA = 1;
oper->NumberB = 2;
printf("%f",oper->GetResult());
delete oper;
return 0;
}
運行結果:
3.0000
所有文件打包下載
posted @
2011-04-28 22:53 lwch 閱讀(1708) |
評論 (0) |
編輯 收藏
設計模式學習筆記
http://m.shnenglu.com/lwch
lwch4@163.com
一、 設計模式概述
a) 簡單工廠模式
b) 策略模式
c) 裝飾模式
d) 代理模式
e) 工廠方法模式
f) 原型模式
g) 模板方法模式
h) 外觀模式
i) 建造者模式
j) 觀察者模式
k) 抽象工廠模式
l) 狀態模式
m) 適配器模式
n) 備忘錄模式
o) 組合模式
p) 迭代器模式
q) 單例模式
r) 橋接模式
s) 命令模式
t) 職責鏈模式
u) 中介者模式
v) 享元模式
w) 解釋器模式
x) 訪問者模式
二、 設計模式應用
所有代碼及部分資料出自《大話設計模式》
posted @
2011-04-28 21:47 lwch 閱讀(725) |
評論 (1) |
編輯 收藏
修正了詞法分析器的一些Bug.
修正了一些運行時的Bug.
支持了單行注釋//和多行注釋/* */
支持了所有的函數聲明形式.
ESEngine_Demo5.rar
posted @
2011-03-02 13:20 lwch 閱讀(1567) |
評論 (3) |
編輯 收藏
繼上篇
《簡單堆結構的實現》之后修改了下代碼,使內存的分配效率更高.
首先將HeapApplyed和HeapUsed包含進一個結構體HEAPATTR,各占1位.
1 struct HEAPATTR
2 {
3 BYTE HeapApplyed : 1;
4 BYTE HeapUsed : 1;
5 }*HeapAttr;
然后添加了一個HeapCurrent變量用于提高檢索速度.
1 int HeapCurrent;
相應的構造函數和析構函數修改為.
1 Heap(const int Size = 1024 * 300)
2 : HeapLength(Size),HeapCurrent(0),HeapLeft(Size)
3 {
4 HeapData = new CHAR[HeapLength];
5 HeapAttr = new HEAPATTR[HeapLength];
6 memset(HeapData,0,HeapLength);
7 memset(HeapAttr,0,HeapLength);
8 }
9
10 ~Heap()
11 {
12 delete[] HeapData;
13 delete[] HeapAttr;
14 }
注意:一個HEAPATTR結構占1個字節,實際上使用的只有2位,編譯器自動為其補齊6位形成1字節(既然只有TRUE和FALSE沒理由要用HeapLength*2字節
)
修改GetEmptyAddr算法,使其提升效率.
1 CHAR* GetEmptyAddr(const int Size)
2 {
3 int Left = 0;
4 for(int i=HeapCurrent;i<HeapLength;i++)
5 {
6 if(HeapAttr[i].HeapApplyed && !HeapAttr[i].HeapUsed) Left++;
7 else Left = 0;
8 if(Left == Size) return HeapData + i - Left + 1;
9 }
10 if(HeapCurrent > 0 && HeapCurrent > Size)
11 {
12 Left = 0;
13 for(int i=0;i<HeapCurrent;i++)
14 {
15 if(HeapAttr[i].HeapApplyed && !HeapAttr[i].HeapUsed) Left++;
16 else Left = 0;
17 if(Left == Size) return HeapData + i - Left + 1;
18 }
19 }
20 return 0;
21 }
同時也將GetEmptyLeft修改為.
1 inline int GetEmptyLeft(int Size)
2 {
3 int Left = 0;
4 for(int i=HeapCurrent;i<HeapLength;i++)
5 {
6 if(!HeapAttr[i].HeapApplyed) Left++;
7 else Left = 0;
8 if(Left == Size) return i - Left + 1;
9 }
10 if(HeapCurrent > 0 && HeapCurrent > Size)
11 {
12 Left = 0;
13 for(int i=0;i<HeapCurrent;i++)
14 {
15 if(!HeapAttr[i].HeapApplyed) Left++;
16 else Left = 0;
17 if(Left == Size) return i - Left + 1;
18 }
19 }
20 return 0;
21 }
添加DumpFile函數生成Dump文件.
1 BOOL DumpFile(CHAR* FileName)
2 {
3 FILE* fp = fopen(FileName,"wt+");
4 fwrite(HeapData,HeapLength,sizeof(CHAR),fp);
5 fclose(fp);
6 return TRUE;
7 }
最后給出
完整代碼
posted @
2011-02-22 17:29 lwch 閱讀(1906) |
評論 (1) |
編輯 收藏
摘要: Lambda表達式提供了匿名函數這個概念,可以使您在一個函數中書寫另一個匿名的函數體先來看下如何在VC2010中書寫Lambda表達式
[捕捉項表](參數表)->返回類型{函數體}捕捉項表中在變量前添加&操作符表示捕捉引用,添加=表示捕捉值參數表與"->"和后面的返回類型是可選的編譯器會由函數體內的return語句判斷返回類型,當返回類型很復雜時編譯器無法判斷,則必須手動給出...
閱讀全文
posted @
2011-02-17 16:32 lwch 閱讀(2674) |
評論 (0) |
編輯 收藏
我們知道對于一個數據堆,有申請內存塊,釋放內存塊等操作.
應此我們給出3個數組,分別為內存堆,標記數組,使用是否數組和一個變量用于表示內存堆內剩余空間數.
1 CHAR HeapData[HEAP_LENGTH];
2 CHAR HeapApplyed[HEAP_LENGTH];
3 CHAR HeapUsed[HEAP_LENGTH];
4
5 int HeapLeft; // 剩余Heap大小
初始化時將3個數組全部設為0.
1 memset(HeapData,0,HEAP_LENGTH);
2 memset(HeapApplyed,0,HEAP_LENGTH);
3 memset(HeapUsed,0,HEAP_LENGTH);
然后我們需要一個New操作來申請一塊尚未使用的內存塊.
1 CHAR* New(const int Size)
2 {
3 if(Size > HeapLeft) throw HEAP_OVERFLOW;
4 int iEmpty = GetEmptyLeft(Size);
5
6 memset(HeapApplyed + iEmpty,1,Size); // 將內存塊標記
7
8 HeapLeft -= Size;
9 return HeapData + iEmpty;
10 }
一個Free操作來釋放一個內存塊.
1 BOOL Free(const int Offset,const int Size)
2 {
3 if(!Apply(Offset,Size)) throw HEAP_NOTAPPLY;
4 memset(HeapApplyed + Offset,0,Size); // 設置為未標記
5 memset(HeapUsed + Offset,0,Size); // 標記為未使用
6 HeapLeft += Size;
7 return TRUE;
8 }
一個GetEmptyAddr操作來獲得第一個符合指定大小的空閑內存卡塊.
1 CHAR* GetEmptyAddr(const int Size)
2 {
3 for(int i=0;i<HEAP_LENGTH;i++)
4 if(HeapApplyed[i] && !HeapUsed[i]) // 已標記并未使用
5 {
6 BOOL bContinue = FALSE;
7 for(int j=i;j<Size;j++)
8 if(!HeapApplyed[j] || HeapUsed[j]) // 未標記或已使用
9 {
10 bContinue = TRUE;
11 break;
12 }
13 if(bContinue) continue;
14 return HeapData + i;
15 }
16 return 0;
17 }
和一個SetData操作來設置數據.
1 BOOL SetData(const int Offset,const Type* Data,const int Size)
2 {
3 if(!Apply(Offset,Size)) throw HEAP_NOTAPPLY;
4 memcpy(HeapData + Offset,Data,Size); // 拷貝數據
5 memset(HeapUsed + Offset,1,Size); // 標記為已使用
6 return TRUE;
7 }
最后我們來測試一下這個堆結構.
1 try
2 {
3 Heap<CHAR> heap;
4 heap.New(9000);
5
6 int i = 1000;
7 heap.Free(0,100);
8 printf("EmptyAddr:%X\n",heap.GetEmptyAddr(sizeof(int)));
9
10 int* Addr1 = (int*)heap.GetEmptyAddr(sizeof(int));
11 heap.SetData((CHAR*)Addr1 - *heap,(CHAR*)&i,sizeof(int));
12
13 printf("The Data In Heap:%d\n",*Addr1);
14
15 heap.New(100);
16 printf("EmptyAddr:%X\n",heap.GetEmptyAddr(sizeof(int)));
17
18 CHAR str[] = "aaaaa";
19 CHAR* Addr2 = heap.GetEmptyAddr(strlen(str));
20 heap.SetData(Addr2 - *heap,str,strlen(str));
21
22 printf("The Data In Heap:%s\n",Addr2);
23
24 printf("EmptyAddr:%X\n",heap.GetEmptyAddr(sizeof(int)));
25 }
26 catch(int i)
27 {
28 switch(i)
29 {
30 case HEAP_OVERFLOW:
31 printf("堆溢出\n");
32 break;
33 case HEAP_NOTAPPLY:
34 printf("錯誤的地址\n");
35 break;
36 }
37 }
測試結果:
1 EmptyAddr:4EFB0
2 The Data In Heap:1000
3 EmptyAddr:4EF4C
4 The Data In Heap:aaaaa
5 EmptyAddr:4EF51
下面給出
完整代碼
posted @
2011-02-15 20:59 lwch 閱讀(2080) |
評論 (3) |
編輯 收藏
添加了DLL的支持(見Samples下的TestDLL.dll)
ESEngine_Demo4.rar
posted @
2011-02-13 19:20 lwch 閱讀(1687) |
評論 (1) |
編輯 收藏
可能還有大量的Bug,請反饋給QQ:510134884.
QLanguage的發展需要您的支持
開源項目地址:http://qlanguage.codeplex.com/
Demo5:
修正了詞法分析器的一些Bug.
修正了一些運行時的Bug.
支持了單行注釋//和多行注釋/* */
支持了所有的函數聲明形式.
http://m.shnenglu.com/lwch/archive/2011/03/02/140979.html
Demo4:
添加了DLL的支持(見Samples下的TestDLL.dll)
http://m.shnenglu.com/lwch/archive/2011/02/13/139989.html
Demo3:
修正了return語句的一些Bug
添加了COM組件的支持(見Samples目錄下的factorial.txt)
http://m.shnenglu.com/lwch/archive/2011/02/07/139787.html
Demo2:
1.修正了函數調用時的一些Bug
2.示例中增加了一個遞歸求階乘的例子
http://m.shnenglu.com/lwch/archive/2011/01/30/139624.html
Demo1:
運行方法:
1.打開命令行提示符
2.cd ESEngine.exe所在路徑
3.ESEngine xxx.txt 1.Samples文件夾下有幾個例子
2.函數目前只寫了
"function" "{Symbol}" "{LQ}" "{RQ}" stmt_list "end" "function"
"function" "{Symbol}" "{LQ}" "{RQ}" "end" "function"
"function" "{Symbol}" "{LQ}" paramter_list "{RQ}" "as" var_type stmt_list "end" "function"
這三類,所以對于
function mn(integer s)
stmts
end function
在生成語法樹時會產生錯誤
http://m.shnenglu.com/lwch/archive/2011/01/28/139546.html
posted @
2011-02-13 00:09 lwch 閱讀(372) |
評論 (2) |
編輯 收藏