饭中淹的避难所~~~~~
偶尔来避难的地方~
C++博客
::
首页
::
新随笔
::
联系
::
聚合
::
管理
::
21 随笔 :: 0 文章 :: 90 评论 :: 0 Trackbacks
<
2008年10月
>
日
一
二
三
四
五
六
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
公告
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
(1)
给我留言
查看公开留言
查看私人留言
随笔档案
2008年6月 (2)
2008年4月 (10)
2007年5月 (1)
2007年4月 (7)
2007年3月 (1)
新闻档案
2007年5月 (1)
我的其他BLOG
搜索
最新评论
1. re: 一种经典的网络游戏服务器架构
game可以根据消息号作处理了,agent仅仅是个门,负责进出
--非风
2. re: 使用IOCP需要注意的一些问题~~(不断补充)
12条:
“这样做就需要减少工作线程的负担,确保工作线程内部要处理费时的工作。”
是不是应该为
“确保工作线程内部_不_要处理费时的工作。”?
--proguru
3. re: 一种经典的网络游戏服务器架构
评论内容较长,点击标题查看
--XiaoA
4. re: 一种经典的网络游戏服务器架构
评论内容较长,点击标题查看
--饭中淹
5. re: 一种经典的网络游戏服务器架构
评论内容较长,点击标题查看
--非风
阅读排行榜
1. 一种经典的网络游戏服务器架构(3778)
2. 使用IOCP需要注意的一些问题~~(不断补充)(2058)
3. 对string类的思考(1968)
4. 使用C++编写插件动态链接库需要注意的问题(不断补充)(1306)
5. 2D砖块地图系统中,自动砖块拼接的方法.(1212)
评论排行榜
1. 一种经典的网络游戏服务器架构(23)
2. 通用的类成员函数调用方法.(12)
3. 对string类的思考(9)
4. 使用IOCP需要注意的一些问题~~(不断补充)(7)
5. 使用C++编写插件动态链接库需要注意的问题(不断补充)(7)
搭建通用构造器
1- 我们来确定我们的目标
我们需要事先一个叫做xCreator的模板类,能够根据一个基类TBase实例化出一个构造器类,能够通过Support<TObject>()的形式来支持TBase的派生类TObject,并能够通过 Create<TObject>() 的形式来构造出这个TObject的对象。
2- 思考我们事先这个目标的理论基础
我们需要为每个TObject,创建一个单独的内部构造器,在Support调用的时候,创建并存储这个内部构造器。当Create调用的时候,我们寻找这个内部构造器,并且通过这个构造器构造出TObject的对象。
3- 内部构造器
在设计内部构造器的时候,因为需要一个通用的返回TBase的接口,所以,我们把这个接口做成一个虚接口。
class
xBaseCreator
{
public
:
virtual TBase
*
CreateObject()
=
0
;
}
;
接下来,就是用模板来实现TObject的构造器了。
template
<
class
TObject
>
class
xObjectCreator :
public
xBaseCreator
{
public
:
TBase
*
CreateObject()
{
return
new
TObject();}
}
;
有了内部的构造器,我们构造出外部的框架xCreator
template
<
class
TBase
>
class
xCreator
{
class
xBaseCreator
{
public
:
virtual TBase
*
NewObject()
=
0
;
}
;
template
<
class
TObject
>
class
xObjectCreator :
public
xBaseCreator
{
public
:
TBase
*
CreateObject()
{
return
new
TObject();}
}
;
public
:
template
<
class
TObject
>
void
Support()
{
}
template
<
class
TObject
>
TBase
*
Create()
{
}
}
;
现在,这个构造器已经有了雏形。
4- 实现Support
Support说白了,就是通过TObject来创建一个内部构造器,并保存在xCreator<TBase>里面。
那么我们需要在这个框架里加入一个容器来存储一系列的内部构造器。
xVector
<
xBaseCreator
*>
m_vInnerCreators;
这里用的xVector是xlibplus的一部分,实际上它表现的跟STL的vector很相似,可以互换使用。
下面就是Support的实际代码,很简单的一句(没有做一些安全性和重复的检测)
template
<
class
TObject
>
void
Support()
{
m_vInnerCreators.push_back(
new
xObjectCreator
<
TObject
>
() );
}
5- 实现Create
Create是整个构造器的重头戏。我们需要找到一种方法,能够通过TObject来找到它所对应的内部构造器。
我们知道,同一个类中的静态成员的地址对于所有类成员来说,是一个相同的固定的地址。这样,这个地址,就可以标示一个特定的类。
然后,我们知道,模板参数相同的模板类实例类,是同一个类。
根据这两个,我们能够设计一种方法,通过静态成员的地址,来找到TObject对应的内部构造器的方法。下面就是这种方法的代码。
首先,修改xBaseCreator的接口,提供一个获取类的Code的接口,这个Code就是模板类中的一个静态变量的地址。
class
xBaseCreator
{
public
:
virtual TBase
*
CreateObject()
=
0
;
virtual
void
*
GetClassCode()
=
0
;
}
;
然后,修改xObjectCreator,提供一个静态变量,以及GetClassCode()的实现。
template
<
class
TObject
>
class
xObjectCreator :
public
xBaseCreator
{
public
:
static
void
*
GetCode()
{
static
int
nClassCode
=
0
;
return
&
nClassCode;
}
void
*
GetClassCode()
{
return
GetCode();}
TBase
*
CreateObject()
{
return
new
TObject();}
}
;
最后,我们把Create写好。
template
<
class
TObject
>
TBase
*
Create()
{
void
*
pClassCode
=
xObjectCreator
<
TObject
>
::GetCode();
for
(
int
i
=
0
;i
<
m_vInnerCreators.size();i
++
)
if
( m_vInnerCreators[i]
->
GetClassCode()
==
pClassCode )
return
m_vInnerCreators[i]
->
CreateObject();
return
NULL;
}
从代码中可以看出整个方法都集中在这个Create里面的内部构造器搜索上面。这种方法有点类似RTTI。
到现在为止,这个通用构造器就基本完成了。代码比较糙,只是用来说明这个方法。至于删除之类的代码,就比较简单了.
下面是完整的这个构造器的代码,以及测试代码。
#include
"
stdafx.h
"
#include
<
conio.h
>
template
<
class
TBase
>
class
xCreator
{
class
xBaseCreator
{
public
:
virtual TBase
*
CreateObject()
=
0
;
virtual
void
*
GetClassCode()
=
0
;
}
;
template
<
class
TObject
>
class
xObjectCreator :
public
xBaseCreator
{
public
:
static
void
*
GetCode()
{
static
int
nClassCode
=
0
;
return
&
nClassCode;
}
void
*
GetClassCode()
{
return
GetCode();}
TBase
*
CreateObject()
{
return
new
TObject();}
}
;
xVector
<
xBaseCreator
*>
m_vInnerCreators;
public
:
template
<
class
TObject
>
void
Support()
{
m_vInnerCreators.push_back(
new
xObjectCreator
<
TObject
>
() );
}
template
<
class
TObject
>
TBase
*
Create()
{
void
*
pClassCode
=
xObjectCreator
<
TObject
>
::GetCode();
for
(
int
i
=
0
;i
<
m_vInnerCreators.size();i
++
)
if
( m_vInnerCreators[i]
->
GetClassCode()
==
pClassCode )
return
m_vInnerCreators[i]
->
CreateObject();
return
NULL;
}
}
;
class
CBase
{
public
:
virtual
int
GetCode()
const
{
return
0
;}
}
;
class
CTest1 :
public
CBase
{
public
:
virtual
int
GetCode()
const
{
return
1
;}
}
;
class
CTest2 :
public
CBase
{
public
:
virtual
int
GetCode()
const
{
return
2
;}
}
;
xCreator
<
CBase
>
testcreator;
int
_tmain(
int
argc, _TCHAR
*
argv[])
{
testcreator.Support
<
CTest1
>
();
testcreator.Support
<
CTest2
>
();
CBase
*
p1
=
testcreator.Create
<
CTest1
>
();
CBase
*
p2
=
testcreator.Create
<
CTest2
>
();
printf(
"
code = %u / %u\n
"
, p1
->
GetCode(), p2
->
GetCode() );
getch();
return
0
;
}
posted on 2008-04-01 02:22
饭中淹
阅读(1001)
评论(6)
编辑
收藏
引用
评论
#
re: 搭建通用构造器
2008-04-01 09:05
梦在天涯
有新意!
回复
更多评论
#
re: 搭建通用构造器
2008-04-01 09:48
raof01
不错。不过我认为xObjectCreator不需要继承xBaseCreator——已经通过模板来得到一定的多态性了。
回复
更多评论
#
re: 搭建通用构造器
2008-04-01 09:53
饭中淹
@raof01
我为了实现无差别的遍历, 所以让他继承.
回复
更多评论
#
re: 搭建通用构造器
2008-04-01 10:06
mm
哎,直接用map不就得了,还用vector
回复
更多评论
#
re: 搭建通用构造器
2008-04-01 10:14
饭中淹
@mm
用map和vector根这个方法无关。用vector比较好理解这个查找过程。
回复
更多评论
#
re: 搭建通用构造器
2008-04-03 12:46
w11
师傅,您好,哈哈,
想不到又碰见我吧
回复
更多评论
刷新评论列表
标题
姓名
主页
验证码
*
内容(提交失败后,可以通过“恢复上次提交”恢复刚刚提交的内容)
Remember Me?
登录
使用高级评论
新用户注册
返回页首
恢复上次提交
[使用Ctrl+Enter键可以直接提交]
相关链接:
网站导航:
博客园
BlogJava
博客生活
IT博客网
C++博客
PHP博客
博客园社区
管理博客
教师博客
天文博客
汽车博客
足球博客
股票博客
电子博客
管理
Powered by:
C++博客
Copyright © 饭中淹