Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site alice.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!alice!bs From: bs@alice.UucP (Bjarne Stroustrup) Newsgroups: net.lang.c++ Subject: pointers to member functions Message-ID: <5196@alice.uUCp> Date: Thu, 27-Mar-86 14:44:26 EST Article-I.D.: alice.5196 Posted: Thu Mar 27 14:44:26 1986 Date-Received: Fri, 28-Mar-86 08:19:14 EST Organization: Bell Labs, Murray Hill Lines: 79 > From: trl@cbrma.UUCP (Tom Lanning) > Subject: pointers to virtual functions > Organization: AT&T-BL, RMAS, Columbus > > Is this a bug in my version of cfront, or a natural attribute of C++? > > class one { > public: > void (*pointer)(); > virtual void x () { cout << "one"; } > > one () { pointer = x; } > }; <> There is more to this than one might expect. Firstly, there are bugs in the program. The assignment ``pointer = x;'' is wrong: ``pointer'' is of the type ``pointer to function taking no argument and returning no value'' but x is of the type ``function member of class one taking no argument and returning no value''. Or viewed from another angle: f(one* p) { (*p->pointer)(); } this call through p->pointer couldn't possibly be to a member function since no object was supplied to the called function. There is also a bug in the compiler: it did not report the error. Sorry. Finally, there is a language problem. How do you get and use pointers to member functions? Using Release 1.0 you have to ``cheat''. Pages 153-154 in the C++ book discusses the problem, shows how to handle pointers to members, and warns that a proper solution is being sought. I now have that solution: ``one::*'' means ``pointer to member of class one'', so I can write: #include struct one { virtual void x () { cout << "one\n"; } }; struct two : one { void x () { cout << "two\n"; } }; typedef void (one::* PoneF)(); // pointer to member of ``one'' void f(PoneF fctptr, one* objptr) { (objptr->*fctptr)(); // call the function obtained // by combining the object pointer // and the member function pointer } main() { one* p = new one; f(&one::x,p); p = new two; f(&one::x,p); } and get the desired output: one two Some day I'll get around to completing the paper describing exactly how this works, why it is useful, and why (in the opinion of me and others) it is the only fully compatible and general solution. Note that pointers to members was the only point where the type system was declared deficient in the book. There is not a horde of such ``little'' problems/fixes in the works. - Bjarne Stroustrup (AT&T Bell Labs, Murray Hill)