精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
锐英源精品开源心得,转载请注明:“锐英源www.wisestudy.cn,孙老师作品,电话13803810136。”需要全文内容也请联系孙老师。
锐英源VC++培训强调关键动手能力,掌握经典开源项目,突出软件工程学习,以互联网和积木式学习法,快速突破到中级程序员水平,适合爱好者和考试者培训学习。
节点是Graph类,它里面有同类指针容器成员,代表相邻节点的集合。
图(vectorGraph)的基类是vector<Graph*>节点的容器,相当于多个节点。
序列化时,用模板函数来进行,为什么可以?因为树形节点和图形节点是类似的,可以归类处理。
模板函数的参数要么是TreeAccess或GraphAccess,这2个类里面成员虽然不一样,但是由下面3条决定了模板函数可以用一个流程来处理:
1、用typedef重新定义类型,比如typedef Graph* Type;
2、序列化成员函数的类型是一样的。
3、同功能的函数同命名,比如Null
GetNeighbors:树取兄弟和子,图从容器集合里得到相邻。
pair:让节点和类型结合,有利于实现序列化。
Serialize<Access>:模板函数的调用,可以带模板参数类型。
map类的find和end函数:find是查找,如果找不到则返回和end()函数一样的结果。
template<class Access>
void Serialize(Access::Type owner,Access::Type current,int currentTyp,
const Access& a,map<Access::Type,int>& mapObjId,int nId)
{
a.ar << currentTyp;
map<Access::Type,int>::const_iterator it= mapObjId.find(current);
bool isPresent=(it==mapObjId.end());
//因为是已经序列化的节点可能是后续节点的相邻节点,所以要用映射来判断当前节点是不是已经序列化了
if(isPresent){//如果没有出现在映射里,代表还没序列化,nId代表了层级,多少级的相邻节点
a.ar << nId;
mapObjId[current]= nId++;//添加到映射
}else{
a.ar << it->second;
}
a.ar << (int)isPresent;
if(isPresent){
a.SerializeThis(owner,current,currentTyp);//序列化节点数据
//找相邻节点,递归调用
vector< pair<Access::Type,int> >vecNeighbors;
a.GetNeighbors(current,vecNeighbors);
a.ar << vecNeighbors.size();
for(int i=0;i<vecNeighbors.size();i++){
Serialize<Access>(current,vecNeighbors[i].first,vecNeighbors[i].second,
a,mapObjId,nId);
}
}
}