home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / lang / cplus / 16758 < prev    next >
Encoding:
Text File  |  1992-11-23  |  2.5 KB  |  85 lines

  1. Path: sparky!uunet!gatech!paladin.american.edu!news.univie.ac.at!hp4at!mcsun!sun4nl!cwi.nl!frans
  2. From: frans@cwi.nl (Frans Heeman)
  3. Newsgroups: comp.lang.c++
  4. Subject: virtual base class and pointer to member function
  5. Message-ID: <7972@charon.cwi.nl>
  6. Date: 23 Nov 92 12:51:52 GMT
  7. Sender: news@cwi.nl
  8. Organization: CWI, Amsterdam
  9. Lines: 74
  10.  
  11. I have a class A that stores a pointer to a member function, that
  12. function being defined in class A or one of its subclasses. If class B
  13. is derived from A, and B defines B::f(), I can store a pointer to B::f()
  14. in A. When I use that member function pointer with an object of type B,
  15. B::f() gets invoked for that object (see code below).
  16.  
  17. However, when I specify A as a *virtual* base class of B, this no
  18. longer works. When I now use the member function pointer with an object
  19. of type B, B::f() gets invoked in the scope of A, even though A does not
  20. define f(). Only when I explicitly cast the type of the function back
  21. to (B::*)(), it gives the same result as above.
  22.  
  23. Which, if any, of the behaviors above is 'correct'?
  24.  
  25. I tried it with both
  26.     <<AT&T C++ Translator 2.00 06/30/89>>
  27. and
  28.     GNU C++ version 2.2.2 [AL 1.1, MM 19] Silicon Graphics Mips
  29.     compiled by GNU C version 2.2.2.
  30.  
  31. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  32. Frans Heeman                                       room: M361
  33. CWI dept. of Interactive Systems                  phone: +31 20 592 4164
  34. Kruislaan 413, 1098 SJ Amsterdam                    fax: +31 20 592 4199
  35. P.O. Box 4079, 1009 AB Amsterdam                 e-mail: frans@cwi.nl
  36. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  37.  
  38. -- Example code---------------------------------------------------------
  39. #include <stream.h>
  40.  
  41. class A; // forward declaration
  42. typedef void (A::*PF)();
  43.     // generic function pointer for A and its subclasses
  44.  
  45.  
  46. class A {
  47.     private:
  48.     int avar;
  49.     public:
  50.     PF pf;
  51.     A();
  52. };
  53.  
  54. A::A() { avar = 10; pf = 0; };
  55.  
  56.  
  57. class B : virtual public A { // try the code without 'virtual' too!
  58.     private:
  59.     int bvar;
  60.     public:
  61.     void f();
  62.     B();
  63. };
  64.     
  65. B::B() : A() { bvar = 5; };
  66. void B::f()  { cout << "in B::f(), bvar = " << bvar << "\n"; cout.flush(); };
  67.  
  68.  
  69. int main()
  70. {
  71.     A a;
  72.     B b;
  73.  
  74.     a.pf = (PF) &B::f;
  75.  
  76.     // call pf through b:
  77.     (b.*(a.pf))();    // prints: in B::f(), bvar = 10
  78.     // should print: in B::f(), bvar = 5
  79.  
  80.     // cast pf to 'void (B::*)()' and call through b:
  81.     void (B::*p1)() = (void(B::*)()) a.pf;
  82.     (b.*p1)();        // prints: in B::f(), bvar = 5
  83.     // this is OK!
  84. }
  85.