整理了下思路,大概就是根据全局的const变量来进行this指针定位,起到了转换的作用。这样一来增加了安全性。大致代码如下:
#include <iostream>
const unsigned __int32 IID_PERSON = 0x11034567;
const unsigned __int32 IID_STUDENT = 0x11065333;
class IObject
{
public:
IObject( void ): m_IID(1){}
virtual ~IObject( void ){}
public:
IObject* DynamicCast( const unsigned __int32 IID ){ if( IID == m_IID ) return this; return VDC( IID ); }
virtual IObject* VDC( const unsigned __int32 IID ){ if( IID == m_IID ) return this; return NULL; }
private:
const unsigned __int32 m_IID;
};
class CPerson :
public IObject
{
public:
CPerson( void ){}
public:
IObject* VDC( const unsigned __int32 IID ){ if( IID == IID_PERSON ) return this; return IObject::VDC( IID ); }
};
class CStudent :
public CPerson
{
public:
CStudent( void ) : level( 100 ) {}
public:
IObject* VDC( const unsigned __int32 IID ){ if( IID == IID_STUDENT ) return this; return CPerson::VDC( IID ); }
public:
int level;
};
int main( void )
{
IObject* p = new CStudent();
CStudent* stu = ( CStudent* )( p->DynamicCast( IID_STUDENT ) );
delete p;
system( "pause" );
return 0;
}
我们用基类的指针去new了CStudent,在任何地方将IObject指针通过DynamicCast(IID)进行定位查找this指针。在上面的例子里面,使用DynamicCast首先调用使this指针是IObject类的(这里虽然是IObject的this,但是所指向的内存块是CStudent的内存块。),通过比较不与m_IID相等,于是调用VDC,而CStudent类重写了VDC且我们new的是CStudent,因而调用到CStudent类的VDC函数。当然此时是相等的,于是返回CStudent类的this指针,之后强制转换成CStudent指针,这时两个this是相等的。。如果此时IID 不等于 IID_STUDENT的话,就会向上去比较CPerson的IID_PERSON,此时不等又返回到IObject类的VDC,不等就返回NULL。这样定位失败返回的指针当然为空了。也不会发生越界等危险。
上面的过程可以根据反汇编清晰的找到调用过程及通过监视变量和寄存器并查看内存获得完美答案。
这里是为了理解这种思想。如果有什么地方说得不对。望各位多多批评和指教。。在此学习了。。