Documente Academic
Documente Profesional
Documente Cultură
Language
Pointers to functions are a surprisingly use-
ful and frequently underutilized feature of
C and C++.
Pointers to Member Functions
Pointers to functions provide an ecient
and eective form of subprogram gener-
ality
Outline { , the qsort standard C library function:
e.g.
f f
public: switch (op)
Screen &repeat (ACTION = &Screen::forward, f
case DOWN: /* code to iterate n times */;
int = 1); break;
/* */ case UP: /* code to iterate n times */;
g;
:::
break;
g
return *this;
g
An invocation of repeat might look as fol-
lows: Pointers to member functions allow a more
general implementation:
Screen my screen;
typedef Screen &(Screen::*ACTION)(void);
/* ::: */ Screen &Screen::repeat (ACTION op, int times)
f
my screen.repeat (); // repeat (&Screen::forward, 1); for (int i = 0; i < times; i++)
my screen.repeat (&Screen::down, 20); (this->*op) ();
return *this;
g
11 12
Example Usage (cont'd) Dierence between PTMF and
PTF
A table of pointers to class members can
also be dened. In the following example, ,
menu is a table of pointers to class Screen
e.g.
&Screen::back; g;
&Screen::up;
&Screen::down; // Pointer to function type
&Screen::bottom; typedef void (*F PTR)(int);
g;
enum Cursor Movements // Pointer to Base 1 member function type
f typedef void (Base 1::*MF PTR)(int);
HOME, FORWARD, BACK, UP, DOWN, BOTTOM
g; void a3 (int i); // Forward decl.
Screen &Screen::move (Cursor Movements cm) class Base 2 f
f public:
(this->*menu[cm])(); void b1 (MF PTR);
return *this; void b2 (F PTR);
g g;
13 14
Contravariance
Just as with data members, we must be Contravariance (cont'd)
careful about contravariance with pointers
to member functions as well.
dp bp
e.g.,
struct Base f
int i; b
i
d
i
virtual int foo (void) f return i; g
g;
struct Derived : public Base f
int j; ? j
virtual int foo (void) f return j; g
g;
void foo (void) f
Base b;
Derived d; Problem: what happens (b.*ptmfg) () is
int (Base::*ptmfb) (void) = &Base::foo; // "ok"
int i = (b.*ptmfb) (); called?
// trouble!
ptmfb = (int (Base::*) (void)) &derived::foo;
int j = (b.*ptmfb) ();
// Tries to access non-existant j part of b!
g
19 20