开发者

Again and again... Pointer to member-function

Suppose:

class Parser
{
  public:
  void parser1(int a, int b, int c);
  void parser2(int d, int e, int f);
  void setupPtr();

  void (Parser::*ptrParser) (int param1, int param2, int param3);
}

Parser::setupPtr()
{
   if(bla bla)
   {
       ptrParser = &Parser::parser1;
   }
   else
   {
       ptrParser = &Parser::parser2;
   }
}

in main:

int main(argv, argc)
开发者_StackOverflow中文版{
   Parser parser;
   parser.setupPtr();
// first case
   parser.ptrParser(some paramps); // error!    error C2064: term does not evaluate to a function taking 3 arguments
// second case
   parser.*ptrParser(some paramps); // error!   'ptrParser' : undeclared identifier
// third case
   (parser.*ptrParser)(some paramps); // error!     'ptrParser' : undeclared identifier


}


Given that you change the ptrParser field to be public, you need to write main this way:

int main()
{
   Parser parser;
   parser.setupPtr();
   (parser .* (parser.ptrParser))(1, 2, 3);
   return 0;
}

Let's try to understand the line.

First, to call a pointer-to-member-function of type void (Parser::*)(int, int, int), given an instance of Parser called inst and a pointer-to-member-function func, the syntax is:

(inst .* func)(x, y, z);

In our case, the instance is named parser and the pointer-to-member-function is stored in the ptrParser field of the parser class that is accessed with the parser.ptrParser syntax. Replacing it in the previous expression, this give us (adding parenthesis because I'm not sure of operator precedence):

(parser .* (parser.ptrParser))(x, y, z);

If instead of a reference or an object we have a pointer to a Parser, the syntax would be:

int main()
{
   Parser *parser = createAndInitializeParser();
   (parser ->* (parser->ptrParser))(1, 2, 3);
   markParserAsNotUsedDestroyIfNeeded(parser);
   return 0;
}


Great intro/tutorial about function pointers in (almost) all shapes and sizes: http://www.newty.de/fpt/index.html

I believe you are looking for part 3.5.


I see two problems with this code.

1) ptrParser is not assigned to anything. You need to call Parser::setupPtr first.

2) ptrParser is a method pointer to a method which takes no parameters, meaning in short that you must define it to contain parameters. I think you could still get away with it if you casted it before calling it, but better to keep such things simple.

Declaration for a method pointer for your particular example would be:

  void (Parser::*ptrParser) (int, int, int);


may I suggest you to make a typedef of your function ptr type :

typedef void (Parser::*funcptr) (int , int , int );

and then create your contener :

class Parser
{
public:
typedef void (Parser::*funcptr) (int , int , int );

void parser1(int a, int b, int c);
void parser2(int d, int e, int f);
void setupPtr();

funcptr firstptr;
}

to set it :

firstptr = &Parser::parser1;

to call it :

Parser foo;
foo.setupPtr;
(foo.*(foo.firstptr))(1, 2, 3);

It's less difficult to understand, and you will be able to create funcptr array...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜