📄 vt_test.cpp
字号:
if( (dc1.*dc1pmf)()==(int)'A' ) n_ok++; dc1pmf = &DC1::B; if( (dc1.*dc1pmf)()==(int)'b' ) n_ok++; return n_ok==5 ? 0 : -1; }class CttClass {public: virtual char* docall TestFunc( int to_add ){_CFE_; return ((char*)this)+to_add; }};typedef char* (docall *Int2CpFn)( void*, int );// Check that we can use the VTable to make an arbitrary call to an index,// with working this pointer and an argument.int CallThisTest(){_CFE_; // Need to run above config function first (VTableEntrySize) if( !g_do_vtbl_es ) return -1; CttClass cttc; void **vtbl = *(void***)&cttc; try{ Int2CpFn i2cfn = (Int2CpFn)vtbl[VTableIndex(0)]; char *pc = i2cfn ? i2cfn(&cttc,100) : NULL; return pc==((char*)&cttc)+100 ? 0 : -1; } catch(...){ return -2; }}class TheBase{public: virtual const char *GetType() const { return "TheBase"; } virtual int AnotherFunc(){_CFE_; return 0; }};class MainBase : public TheBase {public: virtual const char* GetType( ) const { return "MainBase:TheBase"; } virtual int AFunc(){_CFE_; return 3; } int m_mbi; // Assure main base position };class SideBase : public TheBase {public: virtual const char* GetType( ) const { return "SideBase:TheBase"; } int m_sbi;};class MainType : public MainBase, public SideBase {public: virtual const char* GetType( ) const { return "MainType:MainBase,SideBase"; } int m_mti;};class MyType : public MainType {public: virtual const char* GetType( ) const { return "MyType:MainType"; } //virtual void* docall doGetObj(const char* type){ return ::doGetObj((void*)this,doGetType( const DynI **pself ),type); }};// Here we test correcting the VTable for a side base class when using multiple // inheritence. If we have inheritence situation:// A : public B, public C// we want to make sure that if we override function B::f to A::f and there is // also a function C::f, that we can restore C::f, so that it does not end up // in A::f. // This is important, otherwise all sub objects in a compound object will // return the same type. // This feature adjusts the All-or-nothing effect when using virtual functions// for multiple base classes. We can select for which bases we want to override// (the main base is not selectable though).int CorrectVTableTest(){_CFE_; MainType mt, *pmt=&mt; //MainBase mb; MainBase *pmb = (MainBase*)pmt; SideBase *psb = (SideBase*)pmt; if( (void*)psb==(void*)pmt ){ printf("CorrectVTableTest: Unexpected position of side base (before main base?)\n"); return -1; } const char *type = mt.GetType(); const char *mb_type1 = pmb->GetType(); const char *sb_type1 = psb->GetType(); try{ if( MiSideBaseRestoreVTableEntry( pmt, psb, 0 )<0 ) return -2; if( !MiSideBaseSetRamVTable( psb ) ) return -3; } catch (...) { printf("CorrectVTableTest: Catch while calling MiSideBase...\n"); return -4; } const char *mb_type2 = pmb->GetType(); const char *sb_type2 = psb->GetType(); //printf("Before: %s %s\n", mb_type1, sb_type1 ); //printf("After: %s %s\n", mb_type2, sb_type2 ); // If successful, the side base type should be changed now return (mb_type2==mb_type1 && sb_type2!=sb_type1 && sb_type1 && sb_type2) ? 0 : -5;}/* Two tests: 1 - Test for base class layout - do the classes appear in declared order in an instance with multiple bases? 2 - What is the space occupied in an object by a class with only methods?*/// Some bases with only virtual methodsclass V1 {public: virtual int M0(){_CFE_; return 0; }};class V2 {public: virtual int M1(){_CFE_; return 0; } virtual int M2(){_CFE_; return 0; } virtual int M3(){_CFE_; return 0; }};class V3Base1 {public: virtual int M0(){_CFE_; return 0; } virtual int M1(){_CFE_; return 0; }};class V3Base2 {public: virtual int M20(){_CFE_; return 0; } virtual int M21(){_CFE_; return 0; }};class V3 : public V3Base1, public V3Base2 {public: virtual int M0(){_CFE_; return 0; } virtual int M1(){_CFE_; return 0; } virtual int M2(){_CFE_; return 0; } virtual int M3(){_CFE_; return 0; } virtual int M4(){_CFE_; return 0; } virtual int M5(){_CFE_; return 0; } virtual int M6(){_CFE_; return 0; }};// Classes with both virtual methods and dataclass VD1 {public: virtual int M0(){_CFE_; return 0; } char m_buf[100]; int m_i; void *m_pv;};class VD2 : public V2 {public: virtual int M2(){_CFE_; return 2; } virtual int M3(){_CFE_; return 3; } char m_buf[100]; char m_buf1[200]; int m_i; int m_i1; void *m_pv;};class VD3Base {public: int m_vd3i;};class VD3 : public VD3Base, public V3 {public: virtual int M1(){_CFE_; return 1; } virtual int M2(){_CFE_; return 2; } virtual int M3(){_CFE_; return 3; } virtual int M4(){_CFE_; return 4; } long m_ls[100]; VD1 m_vd1; V2 m_v2;};class MBV123 : public V1, public V2, public V3 {public: MBV123(){ g_vt_dummy++; };};class MBV321 : public V3, public V2, public V1 {public: MBV321(){ g_vt_dummy++; };};class MBD123 : public VD1, public VD2, public VD3 {public: MBD123(){ g_vt_dummy++; };};class MBD321 : public VD3, public VD2, public VD1 {public: MBD321(){ g_vt_dummy++; };};class MBM123 : public V1, public VD2, public V3 {public: MBM123(){ g_vt_dummy++; };};class MBM321 : public VD3, public VD2, public V1 {public: MBM321(){ g_vt_dummy++; };};int TripStrInc( void* triple[] ){ return triple[0]<triple[1] && triple[1]<triple[2];}// Returns <0 if some of the tests failsint ObjectLayoutTest(){_CFE_; void *triple[3]; bool results[6]; int n_ok = 0; MBV123 mbv123; triple[0] = (V1*)&mbv123; triple[1] = (V2*)&mbv123; triple[2] = (V3*)&mbv123; if( results[0]=(TripStrInc(triple) && triple[0]==&mbv123) ) n_ok++; MBV321 mbv321; triple[0] = (V3*)&mbv321; triple[1] = (V2*)&mbv321; triple[2] = (V1*)&mbv321; if( results[1]=(TripStrInc(triple) && triple[0]==&mbv321) ) n_ok++; MBD123 mbd123; triple[0] = (VD1*)&mbd123; triple[1] = (VD2*)&mbd123; triple[2] = (VD3*)&mbd123; if( results[2]=(TripStrInc(triple) && triple[0]==&mbd123) ) n_ok++; MBD321 mbd321; triple[0] = (VD3*)&mbd321; triple[1] = (VD2*)&mbd321; triple[2] = (VD1*)&mbd321; if( results[3]=(TripStrInc(triple) && triple[0]==&mbd321) ) n_ok++; MBM123 mbm123; triple[0] = (V1*)&mbm123; triple[1] = (VD2*)&mbm123; triple[2] = (V3*)&mbm123; if( results[4]=(TripStrInc(triple) && triple[0]==&mbm123) ) n_ok++; MBM321 mbm321; triple[0] = (VD3*)&mbm321; triple[1] = (VD2*)&mbm321; triple[2] = (V1*)&mbm321; if( results[5]=(TripStrInc(triple) && triple[0]==&mbm321) ) n_ok++; for( int i=0; i<(int)sizeof(results); i++ ) if( !results[i] ) printf( "ObjectLayoutTest: Failed test %d \n", i ); return n_ok-sizeof(results);}// Returns number of bytes used by an interface in an object int InterfaceSize( ){_CFE_; int if_sz; MBV123 mbv123; MBV321 mbv321; MBM123 mbm123; if_sz = (int)(V2*)&mbv123 - (int)(V1*)&mbv123; if( if_sz!=(int)(V3*)&mbv123 - (int)(V2*)&mbv123 ) return -1; // V3 has two bases with VFuncs if( if_sz!=((int)(V2*)&mbv321 - (int)(V3*)&mbv321)/2 ) return -2; if( if_sz!=(int)(V1*)&mbv321 - (int)(V2*)&mbv321 ) return -3; if( if_sz!=(int)(VD2*)&mbm123 - (int)(V1*)&mbm123 ) return -4; return if_sz;}/*// Here the DoCtor method is invoked to automatically correct // vtable entries for 'local main type' methodsint DoCtorTest(){_CFE_; MainType mt; SideBase *psb = (SideBase*)&mt; DynObjType *ptsb1 = psb->doGetType( const DynI **pself ); try{ mt.DoCtor(); }catch(...){ printf("DoCtorTest: Catch while calling DoCtor\n"); return -1; } DynObjType *ptsb2 = psb->doGetType( const DynI **pself ); return (ptsb1 && ptsb2 && ptsb1!=ptsb2) ? 0 : -2;}*/#endif // VT_ALL_TESTSint doGetDoTraits() {_CFE_; g_do_traits = 0; int off_first; if( VTablePos()<0 || VTableEntrySize(off_first)<0 || InheritPadding()<0 || DtorEntries()<0 || DtorPosition()<0 ) { ; //printf("VTModConstr - Error\n"); g_do_traits |= DO_TRAITS_VT_ERROR; } return g_do_traits;}/*// Run basic tests automatically on load class VTModConstr {public: VTModConstr() { // Run required tests for setting up g_do_traits int of; if( VTablePos()<0 || VTableEntrySize(of)<0 || InheritPadding()<0 || DtorEntries()<0 || DtorPosition()<0 ) { ; //printf("VTModConstr - Error\n"); g_do_traits |= DO_TRAITS_VT_ERROR; } else ; //printf("VTModConstr - Success 0x%08X\n", g_do_traits); } } g_vt_mod_constr;*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -