Guest User

Untitled

a guest
Aug 10th, 2012
19
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.60 KB | None | 0 0
  1. C multiple inheritance and vtables
  2. // Includes
  3. #include <windows.h>
  4. #include <iostream>
  5.  
  6. interface A
  7. {
  8. public:
  9. virtual void OutA() = 0;
  10. };
  11.  
  12. interface B
  13. {
  14. public:
  15. virtual void OutB() = 0;
  16. };
  17.  
  18. class C : public A, public B
  19. {
  20. public:
  21. void OutA();
  22. void OutB();
  23. };
  24.  
  25. void C::OutA()
  26. {
  27. printf("Out An");
  28. }
  29.  
  30. void C::OutB()
  31. {
  32. printf("Out Bn");
  33. }
  34.  
  35. int main()
  36. {
  37. C obj;
  38. obj.OutA();
  39. obj.OutB();
  40.  
  41. A* ap = (A*)&obj;
  42. B* bp = (B*)&obj;
  43.  
  44. ap->OutA();
  45. bp->OutB();
  46.  
  47. system("pause");
  48.  
  49. // Return
  50. return 0;
  51. }
  52.  
  53. Out A
  54. Out B
  55. Out A
  56. Out B
  57.  
  58. #include <stdio.h>
  59. #include <stddef.h>
  60. #include <stdlib.h>
  61.  
  62. const int debug = 0;
  63.  
  64. void __pure_virtual_called() {
  65. fputs ("pure virtual function calledn", stderr);
  66. abort();
  67. }
  68.  
  69. /* Translation of:
  70.  
  71. class A
  72. {
  73. public:
  74. virtual void OutA() = 0;
  75. };
  76. */
  77.  
  78. struct A;
  79.  
  80. typedef struct {
  81. void (*ptr__OutA) (struct A *__this);
  82. } vtable__A;
  83.  
  84. typedef struct A {
  85. vtable__A *__vptr;
  86. } A;
  87.  
  88. /* translation A::OutA()
  89. * pure virtual function */
  90. void A__OutA (A *__this) {
  91. __pure_virtual_called();
  92. }
  93.  
  94. vtable__A vtable__A__A = { .ptr__OutA = A__OutA };
  95.  
  96. void A__constructor (A *__this) {
  97. if (debug)
  98. printf ("A__constructor %pn", (void*)__this);
  99.  
  100. /* dynamic type is initialised to A */
  101. __this->__vptr = &vtable__A__A;
  102. }
  103.  
  104. /* Translation of:
  105.  
  106. class B
  107. {
  108. public:
  109. virtual void OutB() = 0;
  110. };
  111.  
  112. */
  113.  
  114. struct B;
  115.  
  116. typedef struct {
  117. void (*ptr__OutB)(struct B *__this);
  118. } vtable__B;
  119.  
  120. typedef struct B {
  121. vtable__B *__vptr;
  122. } B;
  123.  
  124. /* translation B::OutB()
  125. * pure virtual function */
  126. void B__OutB (B *__this) {
  127. __pure_virtual_called();
  128. }
  129.  
  130. vtable__B vtable__B__B = { .ptr__OutB = B__OutB };
  131.  
  132. void B__constructor (B *__this) {
  133. if (debug)
  134. printf ("B__constructor %pn", (void*)__this);
  135.  
  136. /* dynamic type is initialised to B */
  137. __this->__vptr = &vtable__B__B;
  138. }
  139. /* Translation of:
  140.  
  141. class C : public A, public B
  142. {
  143. public:
  144. void OutA(); // overrides A::OutA()
  145. void OutB(); // overrides B::OutB()
  146. // note :
  147. // no new virtual function
  148. };
  149.  
  150. */
  151.  
  152. /* no new virtual function
  153. * so no specific vtable type! */
  154.  
  155. typedef struct {
  156. /* no additional vptr, we already have 2! */
  157. A base__A;
  158. B base__B;
  159. } C;
  160.  
  161. /******* upcasts
  162. * translation of
  163. * static_cast<C*> (p)
  164. */
  165.  
  166. /* translation of
  167. * A *p;
  168. * static_cast<C*> (p);
  169. */
  170. C *static_cast__A__C (A *__ptr) {
  171. /*
  172. * base__A is first member of C
  173. * so offsetof(C, base__A) == 0
  174. * can skip the pointer adjustment
  175. */
  176. return (C*)__ptr;
  177. }
  178.  
  179. /* translation of
  180. * B *p;
  181. * static_cast<C*> (p);
  182. */
  183. C *static_cast__B__C (B *__ptr) {
  184. /* locate enclosing C object:
  185. * __base__B is not first member
  186. * need to adjust pointer
  187. */
  188. return (C*)((char*)__ptr - offsetof(C, base__B));
  189. }
  190.  
  191. /* translation of virtual functions of C
  192. * overriding function declarations from A
  193. */
  194.  
  195. /* translation of C::OutA() */
  196.  
  197. /* C::OutA() called from C */
  198. void C__OutA (C *__this) {
  199. printf("Out A this=%pn", (void*)__this);
  200. }
  201.  
  202. /* C::OutA() called from A */
  203. void C__A__OutA (A *__this) {
  204. if (debug)
  205. printf ("C__A__OutA %pn", (void*)__this);
  206. C__OutA (static_cast__A__C (__this));
  207. }
  208.  
  209. vtable__A vtable__A__C = { .ptr__OutA = C__A__OutA };
  210.  
  211. /* translation of virtual functions of C
  212. * overriding function declarations from B
  213. */
  214.  
  215. /* translation of C::OutB() */
  216.  
  217. /* C::OutB() called from C */
  218. void C__OutB (C *__this) {
  219. printf("Out B this=%pn", (void*)__this);
  220. }
  221.  
  222. /* C::OutB() called from B */
  223. void C__B__OutB (B *__this) {
  224. if (debug)
  225. printf ("C__B__OutB %pn", (void*)__this);
  226. C__OutB (static_cast__B__C (__this));
  227. }
  228.  
  229. vtable__B vtable__B__C = { .ptr__OutB = C__B__OutB };
  230.  
  231. void C__constructor (C *__this) {
  232. if (debug)
  233. printf ("C__constructor %pn", (void*)__this);
  234. /* construct subobjects */
  235. A__constructor (&__this->base__A);
  236. B__constructor (&__this->base__B);
  237.  
  238. /* adjust dynamic type of this to C */
  239. __this->base__A.__vptr = &vtable__A__C;
  240. __this->base__B.__vptr = &vtable__B__C;
  241. }
  242.  
  243. /* calls to C virtual functions with a C*
  244. */
  245.  
  246. /* translation of
  247. * C *p;
  248. * p->OutA();
  249. *
  250. * is
  251. * ((A*)p)->OutA();
  252. *
  253. * because C::OutA() is overrides A::OutA()
  254. */
  255. void dyn__C__OutA (C *__this) {
  256. A *base_ptr__A = &__this->base__A;
  257. base_ptr__A->__vptr->ptr__OutA (base_ptr__A);
  258. }
  259.  
  260. /* translation of
  261.  
  262. int main()
  263. {
  264. C obj;
  265. obj.OutA();
  266. obj.OutB();
  267.  
  268. A *ap = &obj;
  269. B *bp = &obj;
  270. C *cp = &obj;
  271.  
  272. ap->OutA();
  273. bp->OutB();
  274. cp->OutA();
  275.  
  276. // Return
  277. return 0;
  278. }
  279.  
  280. *
  281. */
  282.  
  283. int main () {
  284. /* translation of:
  285. C obj;
  286. */
  287. C obj;
  288. C__constructor (&obj);
  289.  
  290. /* translation of:
  291. obj.OutA();
  292. obj.OutB();
  293. * obj is a locally declared object
  294. * so dynamic type of obj is known as C
  295. * can make direct call to C::OutA(), C::OutB()
  296. */
  297. C__OutA (&obj);
  298. C__OutB (&obj);
  299.  
  300. /* dumb (zero optimisation) translation of:
  301. A *ap = &obj;
  302. B *bp = &obj;
  303. C *cp = &obj;
  304. */
  305. A *ap = &obj.base__A;
  306. B *bp = &obj.base__B;
  307. C *cp = &obj;
  308.  
  309. /* translation of:
  310. ap->OutA();
  311. bp->OutB();
  312. cp->OutA();
  313.  
  314. * dumb compiler = no optimisation
  315. * so dynamic type of *ap, *bp, *cp is unknown
  316. * so make "virtual" calls using vtable
  317. */
  318. ap->__vptr->ptr__OutA(ap);
  319. bp->__vptr->ptr__OutB(bp);
  320. dyn__C__OutA (cp);
  321.  
  322. /* note: obj lifetime ends now
  323. * C has a trivial destructor
  324. * so no destructor call needed
  325. */
  326.  
  327. return 0;
  328. }
  329.  
  330. Out A this=0xbfeee2ec
  331. Out B this=0xbfeee2ec
  332. Out A this=0xbfeee2ec
  333. Out B this=0xbfeee2ec
  334. Out A this=0xbfeee2ec
  335.  
  336. C obj;
  337. A* ap = (A*)&obj;
  338. B* bp = (B*)&obj;
  339. bool same = ((void*)ap) == ((void*)bp); // false!
Advertisement
Add Comment
Please, Sign In to add comment