摘要: 外观模式
前序
这回小菜同学和大鸟讨论起了关于股票的事情,小菜提到最近股市很火,不过他的同事一直在亏钱。而大鸟说道:“如果你的同事花钱去投资基金,则不会亏的这么厉害。基金将所有投资者的钱全部集中起来,交由专业的经理人进行管理,投资于股票、债券、外汇等领域。”
而个人进行投资股票,对股票的联系太多,反而不利于操作,这在软件中就称为耦合性过高。而有了基金之后,众多的用户只...
阅读全文
posted @
2011-05-26 17:12 lwch 阅读(1611) |
评论 (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 阅读(1624) |
评论 (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 阅读(1995) |
评论 (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 阅读(1820) |
评论 (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 阅读(1936) |
评论 (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 阅读(2629) |
评论 (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 阅读(1349) |
评论 (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 阅读(1696) |
评论 (0) |
编辑 收藏
设计模式学习笔记
http://www.cppblog.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 阅读(717) |
评论 (1) |
编辑 收藏
修正了词法分析器的一些Bug.
修正了一些运行时的Bug.
支持了单行注释//和多行注释/* */
支持了所有的函数声明形式.
ESEngine_Demo5.rar
posted @
2011-03-02 13:20 lwch 阅读(1551) |
评论 (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 阅读(1895) |
评论 (1) |
编辑 收藏
摘要: Lambda表达式提供了匿名函数这个概念,可以使您在一个函数中书写另一个匿名的函数体先来看下如何在VC2010中书写Lambda表达式
[捕捉项表](参数表)->返回类型{函数体}捕捉项表中在变量前添加&操作符表示捕捉引用,添加=表示捕捉值参数表与"->"和后面的返回类型是可选的编译器会由函数体内的return语句判断返回类型,当返回类型很复杂时编译器无法判断,则必须手动给出...
阅读全文
posted @
2011-02-17 16:32 lwch 阅读(2662) |
评论 (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 阅读(2063) |
评论 (3) |
编辑 收藏
添加了DLL的支持(见Samples下的TestDLL.dll)
ESEngine_Demo4.rar
posted @
2011-02-13 19:20 lwch 阅读(1663) |
评论 (1) |
编辑 收藏
可能还有大量的Bug,请反馈给QQ:510134884.
QLanguage的发展需要您的支持
开源项目地址:http://qlanguage.codeplex.com/
Demo5:
修正了词法分析器的一些Bug.
修正了一些运行时的Bug.
支持了单行注释//和多行注释/* */
支持了所有的函数声明形式.
http://www.cppblog.com/lwch/archive/2011/03/02/140979.html
Demo4:
添加了DLL的支持(见Samples下的TestDLL.dll)
http://www.cppblog.com/lwch/archive/2011/02/13/139989.html
Demo3:
修正了return语句的一些Bug
添加了COM组件的支持(见Samples目录下的factorial.txt)
http://www.cppblog.com/lwch/archive/2011/02/07/139787.html
Demo2:
1.修正了函数调用时的一些Bug
2.示例中增加了一个递归求阶乘的例子
http://www.cppblog.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://www.cppblog.com/lwch/archive/2011/01/28/139546.html
posted @
2011-02-13 00:09 lwch 阅读(360) |
评论 (2) |
编辑 收藏