
Pointers to member functions?
Quote:
> An a "C" program, I have these declarations:
> [pointer to a member syntax discussion deleted.]
The other answers in this thread have answered the author's concerns. It
has been my experience that there are usually better ways than pointer to
member functions to select a function at run-time. Lets suppose we have
a set of 3 functions which need to be invoked depending on the situation.
In C pointer to member syntax is used
to cause a method to get selected at runtime, or for use in a callback
function.
Sure it gets the job done, but then the usage is often pretty unwieldly by
the user of the library.
In C++ we usually write classes to be used by others so we want to make
their life as easy as possible. Also
don't forget the plight of the maintenance programmers. To make their lives
easier, with a little more work you
can implement a scheme roughly along these lines. This is pretty crude, but
the idea is
to wrap the function as an object which derives from DoTheRightThing, and
the ctor of DoTheRightThing will
call the right function at runtime.
class DoTheRightThing
{
//This class picks the right method to call given the state of the
constructor. The constructor code
//still has the big ugly switch statment that checks the outer flag. If the
flag is true it searches for the
//right case and creates the appropriate object. I put the ctor at the
bottom of this note.
public:
DoTheRightThing(int arg, bool outer=true);
virtual void operator()(int arg)
{
doit(arg);
}
virtual void doit(int arg)
{
object->doit(arg);
}
virtual ~DoTheRightThing(){if(object)delete object;}
private:
DoTheRightThing* object;
Quote:
};
//These are the function objects we will invoke depending on the
DoTheRightThing argument.
//They each invoke their own version of doit
class f : public DoTheRightThing
{
public:
f(int arg) : DoTheRightThing(arg,false){}
virtual void doit(int arg) { std::cout <<"f was called with arg =
"<<arg<<std::endl; }
Quote:
};
class g : public DoTheRightThing
{
public:
g(int arg) : DoTheRightThing(arg,false){}
virtual void doit(int arg) {
std::cout << "g was called with arg = "<<arg<<std::endl;
}
Quote:
};
class h : public DoTheRightThing
{
public:
h(int arg) : DoTheRightThing(arg,false){}
virtual void doit(int arg) {
std::cout << "h was called with arg = "<<arg<<std::endl;
}
Quote:
};
int main(void)
{
const int DO_F = 1;
DoTheRightThing foo(DO_F);
foo(1);
const int DO_G = 2;
DoTheRightThing bar(DO_G);
bar(10);
const int DO_H = 3;
DoTheRightThing foobar(DO_H);
foobar(30);
return 0;
Quote:
}
DoTheRightThing::DoTheRightThing(int arg, bool outer)
{
object = NULL;
if(outer)
{
switch(arg)
{
case 1:
{
object = new f(arg);
break;
}
case 2:
{
object = new g(arg);
break;
}
case 3:
{
object = new h(arg);
break;
}
default:
{
std::cerr << "unexpected argument to DoTheRightThing"<<std::endl;
break;
}
}//end switch
}//end if
Quote:
}//end ctor