C语言面向对象的构造

13 篇文章 0 订阅
 

1.  define the structure of virtual function table

 

  1. #ifndef __INTERFACE_H__   
  2. #define __INTERFACE_H__   
  3.   
  4.   
  5. //定义一个虚函数表名称   
  6. #define  VTBL(iname)   iname##Vtbl         
  7.   
  8. //定义虚函数表结构   
  9. #define  QINTERFACE(iname) struct _##iname{/   
  10.                                struct VTBL(iname) *pvt;/  
  11.                            };/  
  12.                            struct VTBL(iname)  
  13. //定义一个虚函数表变量   
  14. #define DECLARE_VTBL(iname)      iname vt##iname;   
  15.   
  16. //获取虚函数表的指针   
  17. #define GET_PVTBL(p,iname)       ( (iname *)(void *)p )->pvt   
  18.   
  19. //初始化虚函数表   
  20. #define INIT_VTBL(p,iname,vt)    ( GET_PVTBL(p,iname) = (VTBL(iname) *)(void *)&vt)   
  21.   
  22. //声明基类   
  23. #define DECLARE_IBASE(iname)/   
  24.     int (*AddRef) (iname *);/  
  25.     int (*Release)(iname *);  
  26.   
  27.   
  28. //下面是测试用例   
  29. typedef struct _IList    IList;  
  30. QINTERFACE(IList)  
  31. {  
  32.     DECLARE_IBASE(IList)  
  33.     int (*SetActive)(IList *p, int bSet);  
  34. };  
  35.   
  36. #define ILIST_AddRef(p)      GET_PVTBL( (p), IList)->AddRef( (p) )   
  37. #define ILIST_Release(p)     GET_PVTBL( (p), IList)->Release( (p) )   
  38. #define ILIST_SetActive(p,b) GET_PVTBL( (p), IList)->SetActive( (p) , (b) )   
  39.   
  40.   
  41. #define OBJECT(n)/   
  42.     typedef struct n n;/  
  43.     struct n  
  44.   
  45.   
  46. /*################################################################################*/  
  47. //定义一个虚函数表名称   
  48. #define AEEVTBL(iname) iname##Vtbl   
  49.   
  50. //定义虚函数表结构   
  51. #define AEEINTERFACE(iname)/   
  52.     typedef struct AEEVTBL(iname) AEEVTBL(iname);/  
  53.     struct AEEVTBL(iname)  
  54.   
  55. //获取虚函数表指针   
  56. #define AEEGETPVTBL(p,iname)      ( *( AEEVTBL(iname) **) (void*)p)    
  57.   
  58. //初始化虚函数表   
  59. #define AEEINITVTBL(p,iname,vt)   ( AEEGETPVTBL( (p) ,iname) = (AEEVTBL(iname)*)(&vt) )   
  60.   
  61. //整合了AEEINTERFACE   
  62. #define AEEINTERFACE_DEFINE(iname)/   
  63.     typedef struct iname iname;/  
  64.       AEEINTERFACE(iname){/  
  65.     INHERIT_##iname(iname)/  
  66. };  
  67.   
  68. //下面是测试用例   
  69. typedef  struct TestType TestType;  
  70.   
  71. #define INHERTT_TestType(TestType)/   
  72.     int (*AddRef)(TestType*);/  
  73.     int (*Release)(TestType*);  
  74.      
  75.   
  76. AEEINTERFACE(TestType)  
  77. {  
  78.     INHERTT_TestType(TestType)  
  79.     int (*SetActive)(TestType *p, int bSet);  
  80. };  
  81.   
  82. #define ITESTTYPE_AddRef(p)         (AEEGETPVTBL(p, TestType)->AddRef(p)   
  83. #define ITESTTYPE_Release(p)        (AEEGETPVTBL(p, TestType)->Release(p)   
  84. #define ITESTTYPE_SetActive(p,b)    (AEEGETPVTBL(p, TestType)->SetActive(p,b)   
  85.   
  86.   
  87. #endif  

 

2. define the structure of "class"

 

  1. #include "interface.h"   
  2.   
  3. #include <iostream>   
  4. using namespace std;  
  5.   
  6. OBJECT(List)  
  7. {  
  8.     DECLARE_VTBL(IList)  
  9.   
  10.     int m_nRef;  
  11.   
  12.     int m_nCap;  
  13.     int m_nInc;  
  14. };  
  15.   
  16. static int List_AddRef(IList* p)  
  17. {  
  18.     printf("Call List_AddRef/n");  
  19.     return 0;  
  20. }  
  21.   
  22. static int List_Release(IList* p)  
  23. {  
  24.     printf("Call List_Release/n");  
  25.     return 0;  
  26. }  
  27.   
  28. static int List_SetActive(IList* p,int b)  
  29. {  
  30.     printf("Call List_SetActive/n");  
  31.     return 0;  
  32. }  
  33.   
  34.   
  35. static const VTBL(IList) g_ConstVtbl=  
  36. {  
  37.     List_AddRef,  
  38.     List_Release,  
  39.     List_SetActive,  
  40. };  
  41.   
  42. int TestQInterface()   
  43. {   
  44.     List *pme = (List *)malloc(sizeof(List ));  
  45.     if(!pme)  
  46.     {  
  47.         return 1;  
  48.     }  
  49.   
  50.     IList *po = (IList*)pme;  
  51.     memset(pme, 0x0, sizeof(List));  
  52.     INIT_VTBL(pme, IList, g_ConstVtbl);  
  53.   
  54.     pme->m_nRef = 1;  
  55.   
  56.     //virtual table size: 4 Bytes   
  57.     printf("virtual table size:%d/n",sizeof(VTBL(IList)));  
  58.       
  59.     //object size   
  60.     printf("struct size:%d/n"sizeof(List));  
  61.   
  62.     //member original address   
  63.     printf("original address of member:0x%x/n", &pme->m_nRef);  
  64.   
  65.     //object and virtual original address   
  66.     printf("address of pointer:0x%x/n", pme);  
  67.   
  68.     //the first member(int)   
  69.     printf("value of m_nRef:%d/n", *(int*)((char*)(pme)+4));  
  70.   
  71.     printf("/n");  
  72.     printf("/n");  
  73.   
  74.     ILIST_AddRef(po);  
  75.     ILIST_Release(po);  
  76.     ILIST_SetActive(po, 0);  
  77.   
  78.     printf("/n");  
  79.     printf("/n");  
  80.   
  81.     free(pme);  
  82.     pme = NULL;  
  83.   
  84.     return 0;  
  85. }  
  86.   
  87. struct TestType  
  88. {  
  89.     AEEVTBL(TestType)         *pvt;  
  90.   
  91.     int m_nRef;  
  92.     int m_nCap;  
  93.     int m_nInc;  
  94. };  
  95.   
  96. static int TestType_AddRef(TestType* p)  
  97. {  
  98.     printf("Call TestType_AddRef/n");  
  99.     return 0;  
  100. }  
  101.   
  102. static int TestType_Release(TestType* p)  
  103. {  
  104.     printf("Call TestType_Release/n");  
  105.     return 0;  
  106. }  
  107.   
  108. static int TestType_SetActive(TestType* p,int b)  
  109. {  
  110.     printf("Call TestType_SetActive/n");  
  111.     return 0;  
  112. }  
  113.   
  114.   
  115. static const AEEVTBL(TestType) gTestTypeFuncTbl =  
  116. {  
  117.     TestType_AddRef,  
  118.     TestType_Release,  
  119.     TestType_SetActive,   
  120. };  
  121.   
  122.   
  123. int TestAEEInterface()   
  124. {   
  125.     TestType*pme = (TestType*)malloc(sizeof(TestType));  
  126.     if(!pme)  
  127.     {  
  128.         return 1;  
  129.     }  
  130.   
  131.     AEEVTBL(TestType) *po = ( AEEVTBL(TestType)* )pme;  
  132.     memset(pme, 0x0, sizeof(TestType));  
  133.       AEEINITVTBL(pme, TestType, gTestTypeFuncTbl);  
  134.     //pme->pvt = (AEEVTBL(TestType)*) &gTestTypeFuncTbl;   
  135.   
  136.     pme->m_nRef = 1;  
  137.   
  138.     //virtual table size: 4 Bytes   
  139.     printf("virtual table size:%d/n",sizeof(AEEVTBL(TestType)));  
  140.       
  141.     //object size   
  142.     printf("struct size:%d/n"sizeof(List));  
  143.   
  144.     //member original address   
  145.     printf("original address of member:0x%x/n", &pme->m_nRef);  
  146.   
  147.     //object and virtual original address   
  148.     printf("address of pointer:0x%x/n", pme);  
  149.   
  150.     //the first member(int)   
  151.     printf("value of m_nRef:%d/n", *(int*)((char*)(pme)+4));  
  152.   
  153.     printf("/n");  
  154.     printf("/n");  
  155.   
  156.     TestType_AddRef(pme);  
  157.     TestType_Release(pme);  
  158.     TestType_SetActive(pme,0);  
  159.   
  160.     printf("/n");  
  161.     printf("/n");  
  162.   
  163.     free(pme);  
  164.     pme = NULL;  
  165.   
  166.     return 0;  
  167. }  
  168.   
  169. int main(int argc, char *argv[])  
  170. {  
  171.     TestAEEInterface();  
  172.     return 0;  
  173. }  
  174.   
  175.   
  176. /* 
  177.    之所以为虚函数表申请空间,应该是避免使用全局或者静态的变量来存储虚函数表 
  178.  
  179. int MyFunc_New(IMyFunc **ppo)  
  180.  
  181.     //分配的内存为数据大小+虚表大小 
  182.     CMyFunc *pMe = (CMyFunc *) MALLOC(sizeof(CMyFunc)+sizeof(AEEVTBL(IMyFunc)));  
  183.      
  184.     //使主调函数的指针指向这个对象 
  185.     *ppo = (IMyFunc *)pMe;  
  186.     //0初始化 
  187.     MEMSET(pMe, 0, sizeof(CMyFunc)+sizeof(AEEVTBL(IMyFunc)));  
  188.     //设置成员,第二个参数能计算虚表的开始地址,加的1应为偏移了整个结构大小。 
  189.     //把虚函数表存储在了结构的后面[struct + vtbl] 
  190.     MyFunc_Initialize(pMe, (AEEVTBL(IMyFunc)*)(pMe+1), pIModule, pIShell);  
  191.      
  192.     return SUCCESS;  
  193.  
  194. //设置成员 
  195. static int MyFunc_Initialize(CMyFunc *pMe, AEEVTBL(IMyFunc) *pvt)  
  196.  
  197.     pMe->pvt = pvt;  
  198.     pvt->func1 = ...;  
  199.     ...  
  200. } */  

 

 

3. about the size of structure

 

1)  size of virtual function table

    4 bytes

2)  size of  member variable

 

     0xxxxx  --> original address 

     0xxxxx  --> virtual table          4B

     0xxxxx  --> member 1

     0xxxxx  --> member 2

     0xxxxx  --> member 3

   

4. initialization of stucture.

    

 1)  use static global virtual table.

 

  1. static const VTBL(IList) g_ConstVtbl=  
  2. {  
  3.     List_AddRef,  
  4.     List_Release,  
  5.     List_SetActive,  
  6. };  

 

 2)  use dynamic virtual table

 CMyFunc *pMe = (CMyFunc *) MALLOC(sizeof(CMyFunc)+sizeof(AEEVTBL(IMyFunc)));

 

     0xxxxx  --> original address 

     0xxxxx  --> virtual table          4B

     0xxxxx  --> member 1

     0xxxxx  --> member 2

     0xxxxx  --> member 3

     0xxxxx  --> original address of virtual table

   

将虚函数表存储在结构后面,避免使用全局,静态的存储区
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值