饭中淹的避难所~~~~~
偶尔来避难的地方~
C++博客
::
首页
::
新随笔
::
联系
::
聚合
::
管理
::
94 随笔 :: 0 文章 :: 257 评论 :: 0 Trackbacks
<
2008年4月
>
日
一
二
三
四
五
六
30
31
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
1
2
3
4
5
6
7
8
9
10
公告
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
(19)
给我留言
查看公开留言
查看私人留言
随笔分类
XLIBPLUS(1)
(rss)
手机开发(ios)(2)
(rss)
数据算法分析(19)
(rss)
游戏策划(1)
(rss)
游戏服务器(17)
(rss)
游戏客户端(9)
(rss)
随笔档案
2017年11月 (1)
2013年10月 (1)
2012年12月 (4)
2012年11月 (1)
2012年2月 (2)
2011年10月 (1)
2011年9月 (1)
2011年8月 (3)
2011年7月 (6)
2011年6月 (1)
2011年5月 (2)
2011年4月 (7)
2011年3月 (1)
2011年2月 (5)
2011年1月 (2)
2010年8月 (4)
2010年7月 (1)
2010年5月 (5)
2010年4月 (3)
2010年3月 (3)
2010年2月 (3)
2010年1月 (5)
2009年12月 (1)
2009年11月 (1)
2009年9月 (1)
2009年7月 (1)
2009年6月 (1)
2009年3月 (2)
2009年2月 (1)
2009年1月 (3)
2008年6月 (2)
2008年4月 (10)
2007年5月 (1)
2007年4月 (7)
2007年3月 (1)
新闻档案
2007年5月 (1)
相册
aaa
我的其他BLOG
搜索
最新评论
1. re: 【备忘】Android ndk下用AssetManager读取assets的资源。
能给个完整的吗
--gy
2. re: 【未解决的问题(们)】[未登录]
我们的解决办法是,代码里用英文注释。
--Alex
3. re: 一种经典的网络游戏服务器架构
学习了 make一下
--mikie
4. re: 【备忘】用ndk编译freetype
为什么 我执行 ./configure 时 出现 Nothing to be done for `unix'.
--boom
5. re: 【备忘】Android ndk下用AssetManager读取assets的资源。
谢谢,帮了大忙!!!
--过客
阅读排行榜
1. 一种经典的网络游戏服务器架构(31440)
2. 使用IOCP需要注意的一些问题~~(不断补充)(11379)
3. 【备忘】Android ndk下用AssetManager读取assets的资源。(10293)
4. 【备忘】Android下编译cocos2dx工程(4698)
5. WOF(名将三国)的TGL文件格式(4652)
评论排行榜
1. 一种经典的网络游戏服务器架构(35)
2. WOF(名将三国)的TGL文件格式(19)
3. 使用IOCP需要注意的一些问题~~(不断补充)(16)
4. 通用的类成员函数调用方法.(12)
5. 无锁线程通信(1)(11)
搭建通用构造器
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
饭中淹
阅读(1252)
评论(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
师傅,您好,哈哈,
想不到又碰见我吧
回复
更多评论
刷新评论列表
只有注册用户
登录
后才能发表评论。
【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!
网站导航:
博客园
IT新闻
BlogJava
知识库
博问
管理
Powered by:
C++博客
Copyright © 饭中淹