简体   繁体   中英

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)
{
   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...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM