7.拼了,2000分拿下《MFC 深入浅出》 问题 3 。
ren20 () 2001-02-15 08:51:00 在 VC/MFC / 基础类 提问
每个问题100分,20个问题应该可以拿下深入浅出。呵呵
问题3:
〈MFC深入浅出〉 第109页,关于iskindof 的介绍。
我有一点不明白。
BOOL cobject::IsKindof(const CRuntimeClass *pClass) const
{
CRuntimeClass * pClassThis=GetRuntimeClass();
while(pClassThis!=NULL)
{
if(pClassThis==pClass)
return TRUE;
pClassThis=pClassThis->m_pBaseClass;
}
return FLASE;
}
为什么?判断是否是派生,要用pClassThis==pClass,
这是两个类的CRuntimeclass 的成员指针,
难道同一个类的同一个成员在 这个类的所生成的2个对象中的
地址有什么关系吗?(除了分配的内存大小)
请高手讲解
问题点数:150、回复次数:27
1楼 zhangzhonghua () 回复于 2001-02-15 09:37:00 得分 0
注意:每个类的CRuntimeClass 的成员是static类型的:
#define DECLARE_DYNAMIC(class_name) public: static CRuntimeClass class##class_name; virtual CRuntimeClass *GetRuntimeClass() const;
于是,这些CRuntimeClass objects组成的“网络”是独立于其所描述的类的,在内存中只有一份,如果两个object是属于同一类的话,其CRuntimeClass 的成员指针必定相同(CRuntimeClass objects组成的“网络”在内存中只有一份)!
2楼 zhangzhonghua ()
回复于 2001-02-15 09:50:00 得分 0
你的疑惑在于static成员的用法!
同一个类的同一个成员在这个类的所生成的2个对象中的地址有什么关系吗?
答:如果是非static成员,他们是不同的东西,毫无关系;如果是static成员,他们是同一个东西!
侯哥的另一本书“多型与虚拟”讲得很好!
我的粮仓空虚,如果满意,给我添一点粮吧!
3楼 ren20 ()
回复于 2001-02-15 10:09:00 得分 0
pDoc pulic: document
pmydoc public: pdoc
那pdoc 和pmydoc 有2个CRuntimeclass 对象呀,
因为
static CRuntimeClass class##class_name;
这样好象就不是共享一个了。
4楼 ren20 ()
回复于 2001-02-15 10:09:00 得分 0
指针也不一样了呀 Top
5楼 ren20 ()
回复于 2001-02-15 10:12:00 得分 0
谢谢您耐心的帮助,我会给分。 :) Top
6楼 zhangzhonghua ()
回复于 2001-02-15 10:27:00 得分 0
是的,此时就会运行到这一句:
pClassThis=pClassThis->m_pBaseClass;
7楼 zhangzhonghua () 回复于 2001-02-15 10:33:00 得分 0
你再看:
CRuntimeClass* class_name::GetRuntimeClass() const
{ return &class_name::class##class_name; }
8楼 zhangzhonghua () 回复于 2001-02-15 10:39:00 得分 0
对于static member的继承:
继承得到的是存取权力,而非在derived object中多一份实体空间!
9楼 zhangzhonghua () 回复于 2001-02-15 10:47:00 得分 0
Document - PDoc - PMyDoc
PMyDoc aMyDoc;
aMyDoc.IsKindof(pclassPMyDoc);// 不会走到pClassThis=pClassThis->m_pBaseClass;
aMyDoc.IsKindof(pclassDocument); // 将会走过pClassThis=pClassThis->m_pBaseClass;
10楼 zhangzhonghua () 回复于 2001-02-15 10:53:00 得分 0
那pdoc 和pmydoc 有2个CRuntimeclass 对象呀,
这句话有问题!
11楼 ren20 () 回复于 2001-02-15 11:17:00 得分 0
那pdoc 和pmydoc 各有一个CRuntimeclass 对象呀,
而且不同。
那指针也不一样呀
那还怎么判断?
12楼 ren20 () 回复于 2001-02-15 11:19:00 得分 0
大虾,方便用oicq 联系吗?
又加50分
13楼 zhangzhonghua () 回复于 2001-02-15 11:37:00 得分 0
我不是大虾,也没有oicq(可怜吧?)。
pdoc GetRuntimeClass()得到的是classPDoc, pmydoc GetRuntimeClass()得到的是classPMyDoc,确实不同;但是,classPMyDoc中的m_pBaseClass指向classPDoc(请看#define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew)的具体定义),所以,将会走过pClassThis=pClassThis->m_pBaseClass;
14楼 zhangzhonghua () 回复于 2001-02-15 11:42:00 得分 150
CEdit是CWnd的派生类,IsKindof返回True.
15楼 ren20 () 回复于 2001-02-15 11:43:00 得分 0
哦,我看懂了,非常感谢。
如果愿意指点,请把号码发到 rfa20@371.net
16楼 zhangzhonghua () 回复于 2001-02-15 11:55:00 得分 0
对于类层次:CWnd - CView - CEditView - CMyEditView
有对应的static的CRuntimeClass objects“网络”:classCWnd - classCView - classCEditview - classCMyEditView
CMyEditView::GetRuntimeClass()得到CMyEditView,CEditView::GetRuntimeClass()得到classCEditview,...
其中classCMyEditView的m_pBaseClass指向classCEditview,classCEditview的m_pBaseClass指向classCView,...
这幅图像,现在应该清楚了吧?
17楼 gogocat () 回复于 2001-02-15 12:00:00 得分 0
ren20你有点钻牛角了,你所说的pdoc和pmydoc的CRuntimeclass的确不同,指针也不一样,这都对,但你要记得在IsKindof()函数中是通过循环来检测的
当你执行如下语句
pMyDoc.IsKindOf(RUNTIME_CLASS(pdoc))时我们分解来看:
1.CRuntimeClass* pClassThis=GetRuntimeCalss();//这时pClassThis指向pmydoc的RuntimeClass结构.
2.循环开始
3.if(pClassThis==pClass)
reuturn true;
现在pClassThis指向pmydoc的CRuntimeClass
pClass指向pdoc的CRuntimeClass
两个指针显然不等,所以执行下一条语句。
4.pClassThis=pClassThis->m_pBaseClass;
根据pmydoc CRuntimeClass结构中的m_pBaseClass记录的信息,现在pClassThis变成了指 向pdoc的CRuntimeClass结构。
5.再一次执行if(pClassThis==pClass)
return true;
因为pClassThis是指向pdoc的CRuntimeClass结构,而pClass也是指向pdoc的CRuntimeClass结构,所以,现在pClassThis等于pClass,函数返回TRUE
以上就是分步执行IsKindOf()的过程,
当然如果你执行IsKindOf(RUNTIME_CLASS(CDocument)),同样返回TRUE,只是多循环了一次。
如果你执行IsKindOf(RUNTIME_CLASS(COther)),返回FALSE,因为从pmydoc的CRuntimeClass的m_pBaseClass一路循环上去,也不会得到COther的CRuntimeClass结构。
好了,就写到这里。有不明白的再讨论。
18楼 zhangzhonghua () 回复于 2001-02-15 12:02:00 得分 0
笔误:
CMyEditView::GetRuntimeClass()得到CMyEditView,应该为
CMyEditView::GetRuntimeClass()得到classCMyEditView
希望问题4出来时,我能再补一下仓。
19楼 zhangzhonghua () 回复于 2001-02-15 12:08:00 得分 0
还是gogocat讲得容易听懂。
20楼 ren20 () 回复于 2001-02-15 14:21:00 得分 0
非常感谢两位。 非常感谢
21楼 ren20 () 回复于 2001-02-15 14:36:00 得分 0
没问题呀!
2位,多关注呀,呵呵,我的问题每次都在100分以上。谢谢了
22楼 zhangzhonghua () 回复于 2001-02-15 16:37:00 得分 0
ren20():
有你这样的大鱼大肉报答,辛苦点也不要紧啦!
23楼 ren20 () 回复于 2001-02-15 18:32:00 得分 0
大虾,留下伊妹,否则下回只给90分。 :P
要想从此过,留下你伊妹
24楼 zhangzhonghua () 回复于 2001-02-16 09:31:00 得分 0
我也想留住伊妹呀,但她跟人跑啦。
25楼 hawk_yan () 回复于 2001-02-18 10:51:00 得分 0
这才是市场经济的信誉,这才能使“市场”朝良性循环的方向发展。希望CSDN中能多一点象ren()的信誉良好的顾客,也多一些象zhangzhonghua和gogocat一样的大虾
26楼 ren20 () 回复于 2001-02-19 22:21:00 得分 0
我一般说给多少分就给多少分,言出必行。呵呵
我一般说给多少分就给多少分,言出必行。呵呵
27楼 snowguy (snowguy) 回复于 2001-02-20 11:29:00 得分 0
相关问题