C++ Programmer's Cookbook

{C++ 基础} {C++ 高级} {C#界面,C++核心算法} {设计模式} {C#基础}

石头,剪刀,布(双分派实例)

// : C10:PaperScissorsRock.cpp
//  Demonstration of multiple dispatching
#include  < algorithm >
#include 
< cstdlib >
#include 
< ctime >
#include 
< iostream >
#include 
< iterator >
#include 
< vector >
#include 
" ../purge.h "
using   namespace  std;

class  Paper;
class  Scissors;
class  Rock;

enum  Outcome  { win, lose, draw } ;

ostream
&
operator << (ostream &  os,  const  Outcome  out
{
  
switch ( out {
    
default :
    
case  win:  return  os  <<   " win " ;
    
case  lose:  return  os  <<   " lose " ;
    
case  draw:  return  os  <<   " draw " ;
  }

}


class  Item 
{
public :
  
virtual  Outcome compete( const  Item * =   0 ;
  
virtual  Outcome eval( const  Paper * const   =   0 ;
  
virtual  Outcome eval( const  Scissors * const =   0 ;
  
virtual  Outcome eval( const  Rock * const   =   0 ;
  
virtual  ostream &  print(ostream &  os)  const   =   0 ;
  
virtual   ~ Item()  {}
  friend ostream
&
  
operator << (ostream &  os,  const  Item *  it)  {
    
return  it -> print(os);
  }

}
;

class  Paper :  public  Item 
{
public :
  Outcome compete(
const  Item *  it)  {
    
return  it -> eval( this );
  }

  Outcome eval(
const  Paper * const   {
    
return  draw;
  }

  Outcome eval(
const  Scissors * const   {
    
return  win;
  }

  Outcome eval(
const  Rock * const   {
    
return  lose;
  }

  ostream
&  print(ostream &  os)  const   {
    
return  os  <<   " Paper    " ;
  }

}
;

class  Scissors :  public  Item 
{
public :
  Outcome compete(
const  Item *  it)  {
    
return  it -> eval( this );
  }

  Outcome eval(
const  Paper * const   {
    
return  lose;
  }

  Outcome eval(
const  Scissors * const   {
    
return  draw;
  }

  Outcome eval(
const  Rock * const   {
    
return  win;
  }

  ostream
&  print(ostream &  os)  const   {
    
return  os  <<   " Scissors " ;
  }

}
;

class  Rock :  public  Item 
{
public :
  Outcome compete(
const  Item *  it)  {
    
return  it -> eval( this );
  }

  Outcome eval(
const  Paper * const   {
    
return  win;
  }

  Outcome eval(
const  Scissors * const   {
    
return  lose;
  }

  Outcome eval(
const  Rock * const   {
    
return  draw;
  }

  ostream
&  print(ostream &  os)  const   {
    
return  os  <<   " Rock     " ;
  }

}
;

struct  ItemGen 
{
  ItemGen() 
{ srand(time( 0 )); }
  Item
*   operator ()()  {
    
switch (rand()  %   3 {
      
default :
      
case   0 :
        
return   new  Scissors;
      
case   1 :
        
return   new  Paper;
      
case   2 :
        
return   new  Rock;
    }

  }

}
;

struct  Compete 
{
  Outcome 
operator ()(Item *  a, Item *  b)  {
    cout 
<<  a  <<   " \t "   <<  b  <<   " \t " ;
    
return  a -> compete(b);
  }

}
;

int  main() 
{
  
const   int  sz  =   20 ;
  vector
< Item *>  v(sz * 2 );
  generate(v.begin(), v.end(), ItemGen());
  transform(v.begin(), v.begin() 
+  sz,
    v.begin() 
+  sz,
    ostream_iterator
< Outcome > (cout,  " \n " ),
    Compete());
  purge(v);
}
  /// :~


说是用了双分派,我对这个还不知道哦,希望高手指点哦!

posted on 2007-03-22 17:45 梦在天涯 阅读(2153) 评论(4)  编辑 收藏 引用 所属分类: CPlusPlus

评论

# re: 石头,剪刀,布 2007-03-22 17:57 梦在天涯

看了jacky的c++只支持单分派的文章,还是没有明白哦,谁能够清楚的解释一下哦!  回复  更多评论   

# re: 石头,剪刀,布(双分派实例) 2007-03-23 08:40 LOGOLS OFF

虽然我不清楚模式名称的含义
不过,看这个函数
Outcome compete( const Item * it) {
return it -> eval( this );
}
this指针是的类型是子类,如果你把这个函数写在基类,那也许就编译不了了  回复  更多评论   

# re: 石头,剪刀,布(双分派实例) 2007-03-23 16:45 梦在天涯

刚在visitor设计模式的时候看到的(大家看看有没有道理):

节点调用访问者,将它自己传入,访问者则将某算法针对此节点执行。

双重分派意味着施加于节点之上的操作是基于访问者和节点本身的数据类型,而不仅仅是其中的一者。
  回复  更多评论   

# re: 石头,剪刀,布(双分派实例) 2007-03-23 23:51 LOGOS

嗯,可以这么理解  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

EMail:itech001#126.com

导航

统计

  • 随笔 - 461
  • 文章 - 4
  • 评论 - 746
  • 引用 - 0

常用链接

随笔分类

随笔档案

收藏夹

Blogs

c#(csharp)

C++(cpp)

Enlish

Forums(bbs)

My self

Often go

Useful Webs

Xml/Uml/html

搜索

  •  

积分与排名

  • 积分 - 1795889
  • 排名 - 5

最新评论

阅读排行榜