class DocElementVisitor
{
public :
virtural void VisitParagraph(Paragraph&)=0;
vitrural void VisitRasterBitmap(RasterBitmap&) =0;
}
class DocElement
{
public :
vitual void Accept(DocElementVisitor&)=0;
...
};
void Paragraph::Accept(DocElementVisitor &v)
{
v.VisitParagraph(*this);
}
void RasterBitmap::Accept(DocElementVisitor& v)
{
v.VisitRasterBitmap(*this);
}
class DocStats:public DocElementVisitor
{
public
vitaul void VisitParagraph(Paragraph* par)
{
chars_ +=par.NumChars();
words_ +=par.NumWords();
}
virtual void VisitRasterBitmap(RasterBitmap&)
{
++images_;
}
...
}
void Document::DisplayStatistics()
{
DocStatS statistics;
for(each DocElement in the document)
{
element->Accept(statistics);
}
statistics.Display();
}
某种意义让对象和操作集合在一起,同时优化结构和接口
class IncrementFontSize:public DocElementVistor
{
public:
virtual void VisistParagraph(Paragraph &par)
{
par.SetFontSize(par.GetFontSize()+1);
}
virtual void VisitRasterBitmap(RasterBitmap&)
{
}
}
解决循环依存性,dynamic_cast解决,强制切换到对象
class DocElementVisitor
{
public:
virtual void ~DocElementVisitor(){}
};
public ParagraphVisitor
{
public :
virtual void VisitParagraph(Paragraph&)=0;
}
void Paragraph::Accept(DocElementVisitor&v)
{
if(ParagraphVisitor*p=dynamic_cast<ParagraphVisitor*>(&v))
p->VisitParagraph(*this);
}
else
{
}
}
class DocStats:
public DocElementVisitor,
public ParagraphVisitor,
public RasterBitmapVisitor
{
public :
void VisitParagraph(Paragraph&par)
{
chars_ +=par.NumChars();
words_ +=par.NumWords();
}
void VisitRasterBitmap(RasterBitmap&)
{
++imags;
}
}
泛化Visit
class BaseVisitor
{
public :
Visrtual ~BaseVisitor(){}
};
template <class T ,typename R=void>
class Visitor
{
public:
typedef R ReturnType;
virtual ReturnType Visit(T&)=0;
};
template<typename R=void>
class BaseVisitable
{
public :
typedef R ReturnType;
virtual ~BaseVisitable(){};
virtual R Accept(BaseVisitor&)=0;
protected:
template<class T>
static ReturnType AcceptImpl(T& visited ,BaseVisitor&guest)
{
if(Visitor<T>*p=dynamic_cast<Visitor<T>*>(guest))
return p->Visit(visited);
}
return ReturnType();
};
#define DEFINE_VISITABLE() \
virtual ReturnType Accept(BaseVisitor& guest) {return AcceptImpl(*this,guest);}
泛化visit接口