??xml version="1.0" encoding="utf-8" standalone="yes"?>久久精品国产亚洲AV麻豆网站,国产精品久久国产精品99盘,国产午夜精品久久久久九九http://www.shnenglu.com/tankzhouqiang/category/16137.htmlzh-cnThu, 15 May 2014 03:24:12 GMTThu, 15 May 2014 03:24:12 GMT60skiplisthttp://www.shnenglu.com/tankzhouqiang/archive/2014/05/11/206903.html周强周强Sun, 11 May 2014 15:03:00 GMThttp://www.shnenglu.com/tankzhouqiang/archive/2014/05/11/206903.htmlhttp://www.shnenglu.com/tankzhouqiang/comments/206903.htmlhttp://www.shnenglu.com/tankzhouqiang/archive/2014/05/11/206903.html#Feedback0http://www.shnenglu.com/tankzhouqiang/comments/commentRss/206903.htmlhttp://www.shnenglu.com/tankzhouqiang/services/trackbacks/206903.html

周强 2014-05-11 23:03 发表评论
]]>
Oracle Redo Log 机制 结Q{载)(j)http://www.shnenglu.com/tankzhouqiang/archive/2013/01/08/197126.html周强周强Tue, 08 Jan 2013 11:20:00 GMThttp://www.shnenglu.com/tankzhouqiang/archive/2013/01/08/197126.htmlhttp://www.shnenglu.com/tankzhouqiang/comments/197126.htmlhttp://www.shnenglu.com/tankzhouqiang/archive/2013/01/08/197126.html#Feedback0http://www.shnenglu.com/tankzhouqiang/comments/commentRss/197126.htmlhttp://www.shnenglu.com/tankzhouqiang/services/trackbacks/197126.html阅读全文

周强 2013-01-08 19:20 发表评论
]]>
c++虚函数原理及(qing)实现Q{载)(j)http://www.shnenglu.com/tankzhouqiang/archive/2011/05/11/146186.html周强周强Wed, 11 May 2011 06:13:00 GMThttp://www.shnenglu.com/tankzhouqiang/archive/2011/05/11/146186.htmlhttp://www.shnenglu.com/tankzhouqiang/comments/146186.htmlhttp://www.shnenglu.com/tankzhouqiang/archive/2011/05/11/146186.html#Feedback0http://www.shnenglu.com/tankzhouqiang/comments/commentRss/146186.htmlhttp://www.shnenglu.com/tankzhouqiang/services/trackbacks/146186.html 多态指同一个方法根据其所属的不同对象可以有不同的行ؓ(f)Q根据自q解,不知q么说是否严谨)(j)?

 举个例子说明虚函数、多态、早l定和晚l定Q?br>  李氏两兄妹(哥哥和妹妹)(j)参加姓氏q动?x)(不同姓氏l队参加Q,哥哥男子目比赛Q妹妹参加女子项目比赛,开q式有一个参赛队伍代表发a仪式Q兄妹俩都想 去露露脸Q可只能一人去Q最l他们决定到时抓阄决定,而组委会(x)也不反对Q它才不兛_(j)是哥哥还是妹Ҏ(gu)发言Q只要派一个姓李的来说两句话就行。运动会(x)如期? 行,妹妹抓阄获得代表李家发言的机?x),哥哥参加了(jin)男子项目比赛,妹妹参加了(jin)女子项目比赛。比赛结果就不是我们兛_(j)的了(jin)?br> 现在让我们来做个cLQ只讨论与运动会(x)相关的话题)(j)Q?br> Q?Q类的设计:(x)
  李氏兄妹属于李氏家族Q李氏是基类Q这里还是抽象的U基c)(j)Q李氏又zZ个子c(李氏男和李氏奻I(j)Q李氏男?x)所有男子项目的比赛Q李氏男的成员函 敎ͼ(j)Q李氏女?x)所有女子项目的比赛Q李氏女的成员函敎ͼ(j)。姓李的人都?x)发aQ基c虚函数Q,李氏男和李氏女承自李氏当然也会(x)发言Q只是男奌话声音不一 P内容也会(x)又差异,lh感觉不同Q李氏男和李氏女分别重新定义发言q个虚函敎ͼ(j)。李氏两兄妹是李氏男和李氏女两个类的实体?br> Q?Q程序设计:(x)
 李氏兄妹填写参赛报名表?br> Q?Q编译:(x)
  李氏兄妹的参赛报名表被上交给l委?x)(~译器)(j)Q哥哥和妹妹分别参加男子和女子的比赛Q组委会(x)一看就明白?jin)(早绑定?j)Q只是发a人选不明确Q组委会(x)看到? 名表上写的是“李家代表”Q基cL针)(j)Q组委会(x)不能定到底是谁Q就做了(jin)个备注:(x)如果是男的,是哥哥李某某;如果是女的,是妹妹李某某(晚绑定)(j)。组 委会(x)做好其它准备工作后,qq动?x)开始了(jin)Q编译完毕)(j)?br> Q?Q程序运行:(x)
 q动?x)开始了(jin)Q程序开始运行)(j)Q开q式上我们听C(jin)李家妹妹的发aQ如果是哥哥q气好抓阄胜出,我们听到哥哥的发言Q多态)(j)。然后就是看到兄妹俩参加比赛?jin)。。?/p>

 但愿q个比喻说清楚了(jin)虚函数、多态、早l定和晚l定的概念和它们之间的关pR再说一下,早绑定指~译器在~译期间即知道对象的具体cdq确定此对象调用成员函数的确切地址Q而晚l定是根据指针所指对象的cd信息得到cȝ虚函数表指针q而确定调用成员函数的切地址?br>  

 2、揭密晚l定的秘?/p>

 ~译器到底做?jin)什么实现的虚函数的晚绑定呢Q我们来探个I竟?/p>

  ~译器对每个包含虚函数的cdZ个表Q称为V TA B L EQ。在V TA B L E中,~译器放|特定类的虚函数地址。在每个带有虚函数的c? 中,~译器秘密地|一指针Q称为v p o i n t e rQ羃写ؓ(f)V P T RQ,指向q个对象的V TA B L E?span style="color: #000000;">通过基类指针做虚函数?用时Q也是做多态调用时Q,~译器静(rn)态地插入取得q个V P T RQƈ在V TA B L E表中查找函数地址的代码,q样p调用正确的函C晚捆l发生?/span>为每个类讄V TA B L E、初始化V P T R、ؓ(f)虚函数调用插入代码,所有这些都是自动发生的Q所以我们不必担?j)这些。利用虚函数Q?q个对象的合适的函数p被调用,哪怕在~译器还不知道这个对象的特定cd的情况下。(《C++~程思想?/span>Q?/p>

————这D话U色加粗部分g有点问题Q我个h的理解看后面的ȝ?/span>

 在Q何类中不存在昄的类型信息,可对象中必须存放cM息,否则cd不可能在q行时徏立。那q个cM息是什么呢Q我们来看下面几个类Q?/p>

 class no_virtual
 {
 public:
     void fun1() const{}
     int  fun2() const { return a; }
 private:
     int a;
 }

 class one_virtual
 {
 public:
     virtual void fun1() const{}
     int  fun2() const { return a; }
 private:
     int a;
 }

 class two_virtual
 {
 public:
     virtual void fun1() const{}
     virtual int  fun2() const { return a; }
 private:
     int a;
 }

 以上三个cMQ?br> no_virtual没有虚函敎ͼsizeof(no_virtual)=4Q类no_virtual的长度就是其成员变量整型a的长度;
 one_virtual有一个虚函数Qsizeof(one_virtual)=8Q?br> two_virtual 有两个虚函数Qsizeof(two_virtual)=8Q?nbsp;有一个虚函数和两个虚函数的类的长度没有区别,其实它们的长度就是no_virtual? 长度加一个void指针的长度,它反映出Q如果有一个或多个虚函敎ͼ~译器在q个l构中插入一个指针( V P T RQ。在one_virtual ? two_virtual之间没有区别。这是因为V P T R指向一个存攑֜址的表Q只需要一个指针,因ؓ(f)所有虚函数地址都包含在q个表中?/p>

 q个VPTR可以看作类的类型信息?/p>

 那我们来看看~译器是怎么建立VPTR指向的这个虚函数表的。先看下面两个类Q?br> class base
 {
 public:
     void bfun(){}
     virtual void vfun1(){}
     virtual int vfun2(){}
 private:
     int a;
 }

 class derived : public base
 {
 public:
     void dfun(){}
     virtual void vfun1(){}
     virtual int vfun3(){}
 private:
     int b;
 }

 两个cVPTR指向的虚函数表(VTABLEQ分别如下:(x)
 basec?br>                       —————?br> VPTR—?gt; |&base::vfun1 |
                       —————?br>                  |&base::vfun2 |
                   —————?br>       
 derivedc?br>                       ——————?br> VPTR—?gt; |&derived::vfun1 |
                       ——————?br>                   |&base::vfun2    |
                   ——————?br>                   |&derived::vfun3 |
                    ——————?br>     
  每当创徏一个包含有虚函数的cL从包含有虚函数的cL生一个类Ӟ~译器就个类创徏一个VTABLEQ如上图所C。在q个表中Q编译器攄?jin)在q个c? 中或在它的基cM所有已声明为virtual的函数的地址。如果在q个zcM没有对在基类中声明ؓ(f)virtual的函数进行重新定义,~译器就使用基类 的这个虚函数地址。(在derived的VTABLE中,vfun2的入口就是这U情c(din))(j)然后~译器在q个cM攄VPTR。当使用单承时Q对于每 个对象只有一个VPTR?span style="font-weight: bold; color: #ff0000;">VPTR必须被初始化为指向相应的VTABLEQ这在构造函C发生?/span>
 一旦VPTR被初始化为指向相应的VTABLEQ对象就"知道"它自己是什么类型。但只有当虚函数被调用时q种自我认知才有用?/p>

个hȝ如下Q?/span>
1、从包含虚函数的cL生一个类Ӟ~译器就cdZ个VTABLE。其每一个表Ҏ(gu)该类的虚函数地址?br>2、在定义该派生类对象Ӟ先调用其基类的构造函敎ͼ然后再初始化VPTRQ最后再调用zcȝ构造函敎ͼ 从二q制的视野来看,所谓基cdcL一个大l构体,其中this指针开头的四个字节存放虚函数表头指针。执行子cȝ构造函数的时候,首先调用基类构造函 敎ͼthis指针作ؓ(f)参数Q在基类构造函C填入基类的vptrQ然后回到子cȝ构造函敎ͼ填入子类的vptrQ覆盖基cd入的vptr。如此以来完? vptr的初始化?Q?br>3、在实现动态绑定时Q不能直接采用类对象Q而一定要采用指针或者引用。因为采用类对象传值方式,有(f)时基cd象的产生Q而采用指针,则是通过指针来访问外部的zcd象的VPTR来达到访问派生类虚函数的l果?

 VPTR 常常位于对象的开_(d)~译器能很容易地取到VPTR的|从而确定VTABLE的位|。VPTRL向VTABLE的开始地址Q所有基cd它的子类的虚? 数地址Q子c自己定义的虚函数除外)(j)在VTABLE中存储的位置L相同的,如上面basecdderivedcȝVTABLE中vfun1和vfun2 的地址L按相同的序存储。编译器知道vfun1位于VPTR处,vfun2位于VPTR+1处,因此在用基类指针调用虚函数时Q编译器首先获取指针? 向对象的cd信息QVPTRQ,然后去调用虚函数。如一个basecL针pBase指向?jin)一个derived对象Q那pBase->vfun2 ()被编译器译?nbsp;VPTR+1 的调用,因ؓ(f)虚函数vfun2的地址在VTABLE中位于烦(ch)引ؓ(f)1的位|上。同理,pBase->vfun3 ()被编译器译?nbsp;VPTR+2的调用。这是所谓的晚绑定?/p>

 我们来看一下虚函数调用的汇~代码,以加q解?/p>

 void test(base* pBase)
 {
  pBase->vfun2();
 }

 int main(int argc, char* argv[])
 {
  derived td;
  

 
  test(&td);
  
  return 0;
 }

 derived td;~译生成的汇~代码如下:(x)
  mov DWORD PTR _td$[esp+24], OFFSET FLAT:??_7derived@@6B@ ; derived::`vftable'
  q译器的注释可知,此时PTR _td$[esp+24]中存储的是derivedcȝVTABLE地址?br>  
 test(&td);~译生成的汇~代码如下:(x)
  lea eax, DWORD PTR _td$[esp+24]    
  mov DWORD PTR __$EHRec$[esp+32], 0
  push eax
  call ?test@@YAXPAVbase@@@Z   ; test 
  调用test函数时完成了(jin)如下工作Q取对象td的地址Q将其压栈,然后调用test?/p>

 pBase->vfun2();~译生成的汇~代码如下:(x)
   mov ecx, DWORD PTR _pBase$[esp-4]
  mov eax, DWORD PTR [ecx]
  jmp DWORD PTR [eax+4]
   首先从栈中取出pBase指针指向的对象地址赋给ecxQ然后取对象开头的指针变量中的地址赋给eaxQ此时eax的值即为VPTR的|也就? VTABLE的地址。最后就是调用虚函数?jin),׃vfun2位于VTABLE的第二个位置Q相当于 VPTR+1Q每个函数指针是4个字节长Q所以最后的 调用被编译器译?nbsp;jmp DWORD PTR [eax+4]。如果是调用pBase->vfun1()Q这句就该被~译? jmp DWORD PTR [eax]?br>  

 现在应该对多态、虚函数、晚l定有比较清楚的?jin)解了(jin)吧?br> 

转脓(chung)Qhttp://blog.csdn.net/shenmea00000/archive/2007/10/31/1859762.aspx

周强 2011-05-11 14:13 发表评论
]]>
c++设计模式Q九(ji)Q?抽象工厂QAbstract FactoryQ?/title><link>http://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145613.html</link><dc:creator>周强</dc:creator><author>周强</author><pubDate>Tue, 03 May 2011 15:40:00 GMT</pubDate><guid>http://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145613.html</guid><wfw:comment>http://www.shnenglu.com/tankzhouqiang/comments/145613.html</wfw:comment><comments>http://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145613.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/tankzhouqiang/comments/commentRss/145613.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/tankzhouqiang/services/trackbacks/145613.html</trackback:ping><description><![CDATA[      抽象工厂(Abstract Factory)模式看v来和前面看到的工厂方法很怼Q只是它使用若干工厂Ҏ(gu)(Factory MethodQ模式。每个工厂方法模式创Z个不同类型的对象。当创徏一个工厂对象时Q要军_如何用由那个工厂创徏的所有对象。示例代码如下(假设要创Z个通用的游戏环境,q且希望它能支持不同cd的游戏)(j)Q?br>#include<iostream><br>using namespace std;<br><br>class Obstacle<br>{<br>public:<br>    virtual void action()=0;<br>};<br><br>class Player<br>{<br>public:<br>    virtual void interactWith(Obstacle*)=0;<br>};<br><br>class Kitty: public Player<br>{<br>    virtual void interactWith(Obstacle *ob)<br>    {<br>        cout<<"Kitty has encountered a";<br>        ob->action();<br>    }<br>};<br><br>class KungFuGuy: public Player<br>{<br>    virtual void interactWith(Obstacle* ob)<br>    {<br>        cout<<"KungFuGuy now battles against a";<br>        ob->action();<br>    }<br>};<br>class Puzzle: public Obstacle<br>{<br>public:<br>    void action(){cout<<"Puzzle"<<endl;}<br>};<br><br>class NastyWeapon: public Obstacle<br>{<br>public:<br>    void action(){cout<<"NastyWeapon"<<endl;}<br>};<br><br>//the abstract factory<br>class GameElementFactory<br>{<br>public:<br>    virtual Player* makePlayer()=0;<br>    virtual Obstacle* makeObstacle()=0;<br>};<br><br>//concreate factories<br>class KittiesAndPuzzles:public GameElementFactory<br>{<br>public:<br>    virtual Player* makePlayer(){return new Kitty;}<br>    virtual Obstacle * makeObstacle(){return new Puzzle;}<br>};<br><br>class KillAndDismember:public GameElementFactory<br>{<br>public:<br>    virtual Player* makePlayer(){return new KungFuGuy;}<br>    virtual Obstacle *makeObstacle(){return new NastyWeapon;}<br>};<br><br><br>class GameEnvironment<br>{<br>    GameElementFactory* gef;<br>    Player* p;<br>    Obstacle *ob;<br>public:<br>    GameEnvironment(GameElementFactory * factory)<br>        :gef(factory),p(factory->makePlayer()),ob(factory->makeObstacle()){}<br>    void play(){p->interactWith(ob);}<br>    ~GameEnvironment()<br>    {<br>        delete p;<br>        delete ob;<br>        delete gef;<br>    }<br>};<br><br>int main()<br>{<br>    GameEnvironment<br>        g1(new KittiesAndPuzzles),<br>        g2(new KillAndDismember);<br>    g1.play();<br>    g2.play();<br>}<br><br>在此环境中,Player对象与Obstacle 对象交互Q但是Player和Obstaclecd依赖于具体的游戏。可以选择特定的GameElementFactory来决定游戏的cdQ然后GameEnvironment控制游戏的设|和q行。在本例中,游戏的设|和q行很简单,但是那些动作在很大程度上军_?jin)游戏的l果?br><br><img src ="http://www.shnenglu.com/tankzhouqiang/aggbug/145613.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/tankzhouqiang/" target="_blank">周强</a> 2011-05-03 23:40 <a href="http://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145613.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c++设计模式Q八Q?工厂模式Q封装对象的创徏http://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145610.html周强周强Tue, 03 May 2011 15:12:00 GMThttp://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145610.htmlhttp://www.shnenglu.com/tankzhouqiang/comments/145610.htmlhttp://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145610.html#Feedback0http://www.shnenglu.com/tankzhouqiang/comments/commentRss/145610.htmlhttp://www.shnenglu.com/tankzhouqiang/services/trackbacks/145610.html的工厂方法模式的一U变体。由于每个面向对象应用程序都需要创建对象,q且׃Z可能通过d新类型来扩展应用E序Q工厂模式可能是所有设计模式中最有用的模式之一。实现工厂模式的一U方法就是在基类中定义一个静(rn)态成员函敎ͼCZ如下Q?br>#include<iostream>
#include<stdexcept>
#include<cstddef>
#include<string>
#include<vector>

using namespace std;

class Shape
{
public:
    virtual void draw()=0;
    virtual void erase()=0;
    virtual ~Shape(){}
    class BadShapeCreation :public logic_error
    {
    public:
        BadShapeCreation(string type):
            logic_error("Cannot create type"+type){}
    };
    static Shape* factory(const string &type)
        throw(BadShapeCreation);
};

class Circle:public Shape
{
    Circle(){}
    friend class Shape;
public:
    void draw(){cout<<"Circle::draw"<<endl;}
    void erase(){cout<<"Circle::erase"<<endl;}
    ~Circle(){cout<<"Circle::~Circle"<<endl;}
};

class Square:public Shape
{
    Square(){}
    friend class Shape;
public:
    void draw(){cout<<"Square::draw"<<endl;}
    void erase(){cout<<"Square::erase"<<endl;}
    ~Square(){cout<<"Square::~Square"<<endl;}
};

Shape *Shape::factory(const string & type)
    throw(Shape::BadShapeCreation)
{
    if(type=="Circle")return new Circle;
    if(type=="Square")return new Square;
    throw BadShapeCreation(type);
}

char *sl[]={"Circle","Square","Square","Circle","Circle","Circle","Square"};

int main()
{
    vector<Shape*>shapes;
    try{
        for(size_t i=0;i<sizeof sl/sizeof sl[0];i++)
            shapes.push_back(Shape::factory(sl[i]));
    }catch(Shape::BadShapeCreation e)
    {
        cout<<e.what()<<endl;
        return -1;
    }
    for(size_t i=0;i<shapes.size();i++)
    {
        shapes[i]->draw();
        shapes[i]->erase();
    }
}

函数factory 允许以一个参数来军_创徏何种cd的Shape。在q里Q参数类型ؓ(f)string,也可以是M数据集。ؓ(f)?jin)确保对象的创徏只能发生在函数factory()中,Shape的特定类型的构造函数被设ؓ(f)U有Q同时Shape被声明ؓ(f)友元c,因此factory()能够讉Kq些构造函数?br>
参考:(x) C++~程思想?



周强 2011-05-03 23:12 发表评论
]]>
c++设计模式Q七Q?职责链模式:(x)试采用一pd{略模式http://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145561.html周强周强Tue, 03 May 2011 06:01:00 GMThttp://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145561.htmlhttp://www.shnenglu.com/tankzhouqiang/comments/145561.htmlhttp://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145561.html#Feedback1http://www.shnenglu.com/tankzhouqiang/comments/commentRss/145561.htmlhttp://www.shnenglu.com/tankzhouqiang/services/trackbacks/145561.html     除了(jin)调用一个函数来满某个h以外Q链中的多个函数都有此机?x)满x个请求,因此它有点专家系l的意味。由于职责链实际上就是一个链表,它能够动态创建,因此它可以看做是一个更一般的动态构建的switch语句。示例代码如下:(x)
#include<iostream>
#include<vector>

using namespace std;


enum Answer{NO,YES};

class GimmeStrategy
{
    public:
        virtual Answer canIHave()=0;
        virtual ~GimmeStrategy(){}
};

class AskMom: public GimmeStrategy
{
    public:
        Answer canIHave()
        {
            cout<<"Moom? can I have this?"<<endl;
            return NO;
        }
};

class AskDad: public GimmeStrategy
{
    public:
        Answer canIHave()
        {
            cout<<"Dad,I really need this!"<<endl;
            return NO;
        }
};


class AskGrandpa:public GimmeStrategy
{
    public:
        Answer canIHave()
        {
            cout<<"Grandpa , is it my birthday yet?"<<endl;
            return NO;
        }
};

class AskGrandma:public GimmeStrategy
{
    public:
        Answer canIHave()
        {
            cout<<"Grandma,I really love you!"<<endl;
            return YES;
        }
};

class Gimme:public GimmeStrategy
{
    vector<GimmeStrategy*>chain;
    public:
        Gimme(){
            chain.push_back(new AskMom());
            chain.push_back(new AskDad());
            chain.push_back(new AskGrandpa());
            chain.push_back(new AskGrandma());
        }
        Answer canIHave()
        {
            vector<GimmeStrategy*>::iterator it=chain.begin();
            while(it!=chain.end())
                if((*it++)->canIHave()==YES)
                    return YES;
            cout<<"whiiiiiinnne!"<<endl;
            return NO;
        }
        ~Gimme(){};
};

int main()
{
    Gimme chain;
    chain.canIHave();
}


参?Qc++~程思想卷二



周强 2011-05-03 14:01 发表评论
]]>
c++设计模式Q六Q策略模式:(x)q行旉择法http://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145541.html周强周强Tue, 03 May 2011 03:33:00 GMThttp://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145541.htmlhttp://www.shnenglu.com/tankzhouqiang/comments/145541.htmlhttp://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145541.html#Feedback0http://www.shnenglu.com/tankzhouqiang/comments/commentRss/145541.htmlhttp://www.shnenglu.com/tankzhouqiang/services/trackbacks/145541.html       “{略“的意思就是:(x)可以使用多种Ҏ(gu)来解x个问题,x条大陆通罗马。现在考虑一下忘C(jin)某个人姓名时的情景。这里的E序可以用不同方法解册个问题,实例代码如下Q?br>#include<iostream>

using namespace std;

class NameStrategy
{
    public:
        virtual void greet()=0;
};

class SayHi: public NameStrategy
{
    public:
        void greet()
        {
            cout<<"Hi! How's it going?"<<endl;
        }
};

class Ignore: public NameStrategy
{
    public:
        void greet()
        {
            cout<<"Pretend I don't see you)"<<endl;
        }
};

class Admission:public NameStrategy
{
    public:
        void greet()
        {
            cout<<"I'm sorry ,I forgot your name."<<endl;
        }
};

class Context
{
    NameStrategy & strategy;
    public:
        Context(NameStrategy & strat):strategy(strat){}
        void greet(){strategy.greet();}
};


int main()
{
    SayHi sayhi;
    Ignore ignore;
    Admission admission;
    Context c1(sayhi),c2(ignore),c3(admission);
    c1.greet();
    c2.greet();
    c3.greet();

}

Context::greet()可以正规地写得更加复杂些Q它cM模板Ҏ(gu)模式Q因为其中包含了(jin)不能改变的代码。但在函数main()中可以看刎ͼ可以在运行时q略进行选择。更q一步的做法。可以将状态模式与Context对象的生存期间变化的{略模式l合h使用?br>


周强 2011-05-03 11:33 发表评论
]]>
c++设计模式Q五Q模板方法模?/title><link>http://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145537.html</link><dc:creator>周强</dc:creator><author>周强</author><pubDate>Tue, 03 May 2011 03:15:00 GMT</pubDate><guid>http://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145537.html</guid><wfw:comment>http://www.shnenglu.com/tankzhouqiang/comments/145537.html</wfw:comment><comments>http://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145537.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/tankzhouqiang/comments/commentRss/145537.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/tankzhouqiang/services/trackbacks/145537.html</trackback:ping><description><![CDATA[       应用E序l构框架允许从一个或一l类中承以便创Z个新的应用程序,重用现存cM几乎所有的代码Qƈ且覆盖其中一个或多个函数以便自定义所需要的应用E序。应用程序结构框架中的一个基本的概念是模板方法模式,它很典型地隐藏在覆盖的下方,通过调用基类的不同函数来驱动E序q行?br>      模板Ҏ(gu)模式的一个重要特征是它的定义在基cMQ有时作Z个私有成员函敎ͼ(j)q且不能改动Q模板方法模式就?#8220;坚持相同的代?#8220;。它调用其他基类函数Q就是那些被覆盖的函敎ͼ(j)以便完成其工作,但是客户E序员不必直接调用这些函数。驱动应用程序运行的“引擎”是模板方法模式,CZ代码如下Q?br>#include<iostream><br><br>using namespace std;<br><br>class ApplicationFramework<br>{<br>    protected :<br>        virtual void customize1()=0;<br>        virtual void customize2()=0;<br>    public:<br>        void templateMethod()<br>        {<br>            for(int i=0;i<5;i++)<br>            {<br>                customize1();<br>                customize2();<br>            }<br>        }<br>};<br><br>class MyApp: public ApplicationFramework<br>{<br>    protected:<br>        void customize1(){cout<<"Hello";}<br>        void customize2(){cout<<"World!"<<endl;}<br>};<br><br>int main()<br>{<br>    MyApp app;<br>    app.templateMethod();<br><br>}<br><br>参考:(x)c++~程思想卷二<br><br><img src ="http://www.shnenglu.com/tankzhouqiang/aggbug/145537.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/tankzhouqiang/" target="_blank">周强</a> 2011-05-03 11:15 <a href="http://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145537.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c++设计模式Q四Q适配?Adapter)模式http://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145534.html周强周强Tue, 03 May 2011 02:49:00 GMThttp://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145534.htmlhttp://www.shnenglu.com/tankzhouqiang/comments/145534.htmlhttp://www.shnenglu.com/tankzhouqiang/archive/2011/05/03/145534.html#Feedback0http://www.shnenglu.com/tankzhouqiang/comments/commentRss/145534.htmlhttp://www.shnenglu.com/tankzhouqiang/services/trackbacks/145534.html
实例代码如下Q?br>//FibonacciGenerator.h, 斐L那契数列产生器类

#ifndef FIBONACCIGENERATOR_H
#define FIBONACCIGENERATOR_H

class FibonacciGenerator
{
    int n;
    int val[2];
    public:
        FibonacciGenerator():n(0){val[0]=val[1]=0;}
        int operator()()
        {
            int result=n>2?val[0]+val[1]:n>0?1:0;
            ++n;
            val[0]=val[1];
            val[1]=result;
            return result;
        }
        int count(){return n;}
};
#endif

也许读者希望利用这个生器来执行STL数值算法操作。遗憄是,STL法只能使用q代器才能工作,q就存在接口不匹配的问题。解x法就是生一个适配器。代码如下?br>#include<iostream>
#include<numeric>
#include"FibonacciGenerator.h"

using namespace std;

class FibonacciAdapter
{
    FibonacciGenerator f;
    int length;
    public:
        FibonacciAdapter(int size):length(size){}
        class iterator;
        friend class iterator;
        class iterator:public std::iterator<std::input_iterator_tag,FibonacciAdapter,ptrdiff_t>
        {
            FibonacciAdapter& ap;
            public:
                typedef int value_type;
                iterator(FibonacciAdapter &a):ap(a){}
                bool operator==(const iterator &)const{
                    return ap.f.count()==ap.length;
                }
                bool operator!=(const iterator &x)const
                {
                    return !(*this==x);
                }

                int operator*()const{return ap.f();}
                iterator& operator++(){return *this;}
                iterator operator++(int){return *this;}
        };
        iterator begin(){return iterator(*this);}
        iterator end(){return iterator(*this);}
};

int main()
{
    const int SZ=20;
    FibonacciAdapter a1(SZ);
    cout<<"accumulate:"<<accumulate(a1.begin(),a1.end(),0)<<endl;
}





周强 2011-05-03 10:49 发表评论
]]>
c++设计模式(?代理模式QProxyQ与状态模?State)模式http://www.shnenglu.com/tankzhouqiang/archive/2011/04/28/145229.html周强周强Thu, 28 Apr 2011 08:04:00 GMThttp://www.shnenglu.com/tankzhouqiang/archive/2011/04/28/145229.htmlhttp://www.shnenglu.com/tankzhouqiang/comments/145229.htmlhttp://www.shnenglu.com/tankzhouqiang/archive/2011/04/28/145229.html#Feedback0http://www.shnenglu.com/tankzhouqiang/comments/commentRss/145229.htmlhttp://www.shnenglu.com/tankzhouqiang/services/trackbacks/145229.html      基本思想很简单:(x)代理cL生来自一个基c,由^行地z来自同一个基cȝ一个或多个cL供实际的实现。当一个代理对象被创徏的时候,一个实现对象就分配l了(jin)它,代理对象将函数调用发给实现对象?br>      从结构上来看Q代理模式和状态模式的区别很简单:(x)代理模式只有一个实现类Q而状态模式有多个Q一个以上)(j)实现。认两种设计模式的应用也不同Q代理模式控制对其实现类的访问,而状态模式动态地改变其实现类?br>Q?Q代理模式例子:(x)
#include<iostream>

using namespace std;

class ProxyBase
{
    public:
        virtual void f()=0;
        virtual void g()=0;
        virtual void h()=0;
        virtual ~ProxyBase(){}
};


class Implementation :public ProxyBase
{
    public:
        void f(){cout<<"Implementation.f()"<<endl;}
        void g(){cout<<"Implementation.g()"<<endl;}
        void h(){cout<<"Implementation.h()"<<endl;}
};


class Proxy: public ProxyBase
{
    ProxyBase *implementation;
    public:
        Proxy(){implementation=new Implementation();}
        ~Proxy(){delete implementation;}


        void f(){implementation->f();}
        void g(){implementation->g();}
        void h(){implementation->h();}
};

int main()
{
    Proxy p;
    p.f();
    p.g();
    p.h();
}

Q?Q状态模?br>#include<iostream>

using namespace std;

class Creature
{
    class State
    {
        public:
            virtual string response()=0;
    };

    class Frog : public State
    {
        public:
            string response(){return "Ribbet!";}
    };

    class Prince:public State
    {
        public:
            string response(){return "Darling!";}
    };

    State *state;
    public:
        Creature(): state(new Frog()){}
        void greet()
        {
            cout<<state->response()<<endl;
        }
        void kiss()
        {
            delete state;
            state=new Prince();
        }
};


int main()
{
    Creature creature;
    creature.greet();
    creature.kiss();
    creature.greet();
}



周强 2011-04-28 16:04 发表评论
]]>
c++设计模式( 二)(j) 命o(h)Q选择操作http://www.shnenglu.com/tankzhouqiang/archive/2011/04/28/145212.html周强周强Thu, 28 Apr 2011 06:26:00 GMThttp://www.shnenglu.com/tankzhouqiang/archive/2011/04/28/145212.htmlhttp://www.shnenglu.com/tankzhouqiang/comments/145212.htmlhttp://www.shnenglu.com/tankzhouqiang/archive/2011/04/28/145212.html#Feedback0http://www.shnenglu.com/tankzhouqiang/comments/commentRss/145212.htmlhttp://www.shnenglu.com/tankzhouqiang/services/trackbacks/145212.html#include<iostream>
#include<vector>

using namespace std;

class Command
{
    public:
        virtual void execute()=0;
};


class Hello: public Command
{
    public:
        void execute(){cout<<"hello ";}
};


class World : public Command
{
    public:
        void execute(){cout<<"world!";}
};

class IAm:public Command
{
    public:
        void execute(){cout<<"I'm the command pattern!";}
};

class Macro
{
    vector<Command *>commands;
    public:
        void add(Command *c){commands.push_back(c);}
        void run()
        {
            vector<Command*>::iterator it=commands.begin();
            while(it!=commands.end())
            {
                (*it++)->execute();
                cout<<endl;
            }
            
        }
};


int main()
{
    Macro macro;
    macro.add(new Hello);
    macro.add(new World);
    macro.add(new IAm);
    macro.run();
}

      命o(h)模式的主要特Ҏ(gu)允许向一个函数或者对象传递一个想要的动作。上qC子提供了(jin)一pd需要一h行的动作集进行排队的Ҏ(gu)。在q里Q可以动态创建新的行为,某些事情通常只能通过~写新的代码来完成,而在上述例子中可以通过解释一个脚本来实现?br>
参考:(x)c++~程思想2



周强 2011-04-28 14:26 发表评论
]]>
c++设计模式Q一Q?单gQSingleton)http://www.shnenglu.com/tankzhouqiang/archive/2011/04/28/145192.html周强周强Thu, 28 Apr 2011 02:41:00 GMThttp://www.shnenglu.com/tankzhouqiang/archive/2011/04/28/145192.htmlhttp://www.shnenglu.com/tankzhouqiang/comments/145192.htmlhttp://www.shnenglu.com/tankzhouqiang/archive/2011/04/28/145192.html#Feedback0http://www.shnenglu.com/tankzhouqiang/comments/commentRss/145192.htmlhttp://www.shnenglu.com/tankzhouqiang/services/trackbacks/145192.html
单g也许是最单的设计模式Q它是允怸个类有且仅有一个实例的Ҏ(gu)。创Z个单件模式的关键是防止客L(fng)序员获得M控制其对象生存期的权利。ؓ(f)?jin)做到这一点,声明所有的构造函Cؓ(f)U有Qƈ且防止编译器隐式生成M构造函数。注意,拯构造函数和赋值操作符Q这两个故意没有实现Q,因ؓ(f)它们Ҏ(gu)不会(x)被调用)(j)被声明ؓ(f)U有Q以侉K止Q何这cd制动作生。这U方法ƈ没有限制只创Z个对象。这U技术也支持创徏有限个对象的对象池?br>
下面的程序显C在c++中如何实C个单件模?br>#include<iostream>

using namespace std;


class Singleton
{
    static Singleton s;
    int i;
    Singleton(int x):i(x){}
    Singleton & operator=(Singleton &); //disallowed
    Singleton(const Singleton &);

public:
    static Singleton & instance(){return s;}
    int getValue(){return i;}
    void setValue(int x){i=x;}
};


Singleton Singleton::s(47);


int main()
{
    Singleton &s =Singleton::instance();
    cout<<s.getValue()<<endl;
    Singleton &s2=Singleton::instance();
    s2.setValue(9);
    cout<<s.getValue()<<endl;
}


参考:(x)c++ ~程思想 2



周强 2011-04-28 10:41 发表评论
]]>
þþžžþƷֱ| ɫۺϾþ88ɫۺ| þۺϺݺۺϾþü | þþþavר| þþƷþþþùۿ99ˮ| Ʒþþþþ| þù| RE99þþƷ66| һþþƷһ| þþƷŷƬ| Ļþҹ| 97Ʒ˾þþô߽97| պƷþĻ | 97þóƷɰ| þ×Ʒþþþþ| þþþþùƷ볬| ԴӰȷþԴ| Ʒһþ㽶߿| 2021ٸþþþþþþþ| þùһ| Ժձһձþ | þþþþþ91Ʒѹۿ| ŷ޹Ʒþþþ| ƷۺϾþþþþ97| 99þþƷ| þþþþһƷ| þĻ˿| þþƷ| ŷƷ˿þþĻ| þۺϾƷ| 91þ㽶Ů߿| þ޾Ʒվ | ˾ƷǾþ| þԭƷ| þ޾Ʒһ | þۺϸϾþúݺݺ97ɫ| ޹˾þۺһ| þþþþƷAV | ˾ƷۺϾþþ| 99þþù| պһþ |