tb0268.pp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. { Old file: tbs0312.pp }
  2. { Again the problem of local procs inside methods }
  3. { Program that showss a problem if
  4. Self is not reloaded in %esi register
  5. at entry in local procedure inside method }
  6. uses
  7. objects;
  8. type
  9. {$ifndef FPC}
  10. sw_integer = integer;
  11. {$endif not FPC}
  12. PMYObj = ^TMyObj;
  13. TMyObj = Object(TObject)
  14. x : longint;
  15. Constructor Init(ax : longint);
  16. procedure display;virtual;
  17. end;
  18. PMYObj2 = ^TMyObj2;
  19. TMyObj2 = Object(TMyObj)
  20. y : longint;
  21. Constructor Init(ax,ay : longint);
  22. procedure display;virtual;
  23. end;
  24. PMyCollection = ^TMyCollection;
  25. TMyCollection = Object(TCollection)
  26. function At(I : sw_integer) : PMyObj;
  27. procedure DummyThatShouldNotBeCalled;virtual;
  28. end;
  29. { TMy is also a TCollection so that
  30. ShowMy and DummyThatShouldNotBeCalled are at same position in VMT }
  31. TMy = Object(TCollection)
  32. Col : PMyCollection;
  33. MyObj : PMyObj;
  34. ShowMyCalled : boolean;
  35. constructor Init;
  36. destructor Done;virtual;
  37. procedure ShowAll;
  38. procedure AddMyObj(x : longint);
  39. procedure AddMyObj2(x,y : longint);
  40. procedure ShowMy;virtual;
  41. end;
  42. Constructor TMyObj.Init(ax : longint);
  43. begin
  44. Inherited Init;
  45. x:=ax;
  46. end;
  47. Procedure TMyObj.Display;
  48. begin
  49. Writeln('x = ',x);
  50. end;
  51. Constructor TMyObj2.Init(ax,ay : longint);
  52. begin
  53. Inherited Init(ax);
  54. y:=ay;
  55. end;
  56. Procedure TMyObj2.Display;
  57. begin
  58. Writeln('x = ',x,' y = ',y);
  59. end;
  60. Function TMyCollection.At(I : sw_integer) : PMyObj;
  61. begin
  62. At:=Inherited At(I);
  63. end;
  64. Procedure TMyCollection.DummyThatShouldNotBeCalled;
  65. begin
  66. Writeln('This method should never be called');
  67. Abstract;
  68. end;
  69. Constructor TMy.Init;
  70. begin
  71. New(Col,Init(5,5));
  72. MyObj:=nil;
  73. ShowMyCalled:=false;
  74. end;
  75. Destructor TMy.Done;
  76. begin
  77. Dispose(Col,Done);
  78. Inherited Done;
  79. end;
  80. Procedure TMy.ShowAll;
  81. procedure ShowIt(P : pointer);{$ifdef TP}far;{$endif}
  82. begin
  83. ShowMy;
  84. PMyObj(P)^.Display;
  85. end;
  86. begin
  87. Col^.ForEach(@ShowIt);
  88. end;
  89. Procedure TMy.ShowMy;
  90. begin
  91. if assigned(MyObj) then
  92. MyObj^.Display;
  93. ShowMyCalled:=true;
  94. end;
  95. Procedure TMy.AddMyObj(x : longint);
  96. begin
  97. MyObj:=New(PMyObj,Init(x));
  98. Col^.Insert(MyObj);
  99. end;
  100. Procedure TMy.AddMyObj2(x,y : longint);
  101. begin
  102. MyObj:=New(PMyObj2,Init(x,y));
  103. Col^.Insert(MyObj);
  104. end;
  105. var
  106. My : TMy;
  107. begin
  108. My.Init;
  109. My.AddMyObj(5);
  110. My.AddMyObj2(4,3);
  111. My.AddMyObj(43);
  112. { MyObj field is now a PMyObj with value 43 }
  113. My.ShowAll;
  114. If not My.ShowMyCalled then
  115. begin
  116. Writeln('ShowAll does not work correctly');
  117. Halt(1);
  118. end;
  119. My.Done;
  120. end.