home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!gatech!paladin.american.edu!news.univie.ac.at!hp4at!mcsun!sun4nl!cwi.nl!frans
- From: frans@cwi.nl (Frans Heeman)
- Newsgroups: comp.lang.c++
- Subject: virtual base class and pointer to member function
- Message-ID: <7972@charon.cwi.nl>
- Date: 23 Nov 92 12:51:52 GMT
- Sender: news@cwi.nl
- Organization: CWI, Amsterdam
- Lines: 74
-
- I have a class A that stores a pointer to a member function, that
- function being defined in class A or one of its subclasses. If class B
- is derived from A, and B defines B::f(), I can store a pointer to B::f()
- in A. When I use that member function pointer with an object of type B,
- B::f() gets invoked for that object (see code below).
-
- However, when I specify A as a *virtual* base class of B, this no
- longer works. When I now use the member function pointer with an object
- of type B, B::f() gets invoked in the scope of A, even though A does not
- define f(). Only when I explicitly cast the type of the function back
- to (B::*)(), it gives the same result as above.
-
- Which, if any, of the behaviors above is 'correct'?
-
- I tried it with both
- <<AT&T C++ Translator 2.00 06/30/89>>
- and
- GNU C++ version 2.2.2 [AL 1.1, MM 19] Silicon Graphics Mips
- compiled by GNU C version 2.2.2.
-
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Frans Heeman room: M361
- CWI dept. of Interactive Systems phone: +31 20 592 4164
- Kruislaan 413, 1098 SJ Amsterdam fax: +31 20 592 4199
- P.O. Box 4079, 1009 AB Amsterdam e-mail: frans@cwi.nl
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- -- Example code---------------------------------------------------------
- #include <stream.h>
-
- class A; // forward declaration
- typedef void (A::*PF)();
- // generic function pointer for A and its subclasses
-
-
- class A {
- private:
- int avar;
- public:
- PF pf;
- A();
- };
-
- A::A() { avar = 10; pf = 0; };
-
-
- class B : virtual public A { // try the code without 'virtual' too!
- private:
- int bvar;
- public:
- void f();
- B();
- };
-
- B::B() : A() { bvar = 5; };
- void B::f() { cout << "in B::f(), bvar = " << bvar << "\n"; cout.flush(); };
-
-
- int main()
- {
- A a;
- B b;
-
- a.pf = (PF) &B::f;
-
- // call pf through b:
- (b.*(a.pf))(); // prints: in B::f(), bvar = 10
- // should print: in B::f(), bvar = 5
-
- // cast pf to 'void (B::*)()' and call through b:
- void (B::*p1)() = (void(B::*)()) a.pf;
- (b.*p1)(); // prints: in B::f(), bvar = 5
- // this is OK!
- }
-