1

I'm quite unfamiliar with C++ and I'm having some issues with executing a static member function pointer I've tried several different variations on the code (included below) and looked at several different tutorials and questions but I'm not having much luck!

Here's a code snippet for the header and source files plus the error's I'm getting:Actions.h

class Actions{
private:
    int actionId;
    int stateId;
    int eventId;
public:
    typedef string (Actions::*functionPtr)(int previousState, int currentState, int eventId);
    static functionPtr _ptrAction1;
    int doAction(int previousState, int currentState, int eventId);
    string function1(int previousState, int currentState, int eventId);
};

Actions.c:

#include "stdafx.h"
#include "Actions.h"
Actions::Actions(int actionId, int stateId, int eventId){
    this->actionId = actionId;
    this->stateId = stateId;
    this->eventId = eventId;
    _ptrAction1 = &Actions::function1;
}

int doAction(int actionId, int previousState, int currentState, int eventId){
int functionId = 0;
string message;

switch(actionId){
   case 1:
       message = (*_ptrAction1)(previousState, currentState, eventId);
       break;
   default:
       break;
   }
}

string Actions::function1(int previousState, int currentState, int eventId){
    return "this is an example for now";
}

The error I'm receiving is in Actions.c on line

message = (*_ptrAction1)(previousState, currentState, eventId);

The error is as follows:

1>Actions.cpp(37): error C2065: '_ptrAction1' : undeclared identifier

I thought perhaps I was referencing it incorrectly so I changed the above line to be as follows:

message = (*Actions::_ptrAction1)(previousState, currentState, eventId);

But now I receive a different error:

Actions.cpp(37): error C2064: term does not evaluate to a function taking 3 arguments

For reference I have read C++ calling static function pointer but it is not the same issue that I am having. I really hope you can help and I thank you for your time, I greatly appreciate it!

2
  • 2
    Is that the complete code? You don't implement function1, only define it. Commented Jun 30, 2015 at 20:54
  • Sorry yes this is not the complete code just a snippit I'll include function1 for reference. Commented Jun 30, 2015 at 20:58

2 Answers 2

0

ptrAction1 is static pointer to an object method. function1 is a method on which your pointer points to, so you must call it in an object context.

Suppose that you want to call it on the current object, then *this.*_ptrAction1 is the way to call it in a method.

Your doAction function doesn't use any Actions instance, you then cannot call the method... Define doAction(4 params) as a method of the class or pass a instance as a parameter.

Sign up to request clarification or add additional context in comments.

3 Comments

The relative precedence of * and .* is quite surprising, I almost mistakenly edited to add parentheses.
*this.* .. or this->*
Thank you very much for your concise explanation Jean-Baptiste! I hadn't realised I'd left the Actions:: off of the doAction method (and I feel a little bit silly now)!
0

There's a couple of things going on with your code you have posted:

First, you need to properly declare your Actions::doAction method to match the signature of your other doAction (or vice versa).

Next, since you've declared _ptrAction1 as a static member, you'll need to re-declare for linkage outside of the class (otherwise you'll get undefined reference errors).

After that, then you can call it like so: (this->*_ptrAction1)(...) when you are within an Actions context (that is, you can call this->* when you are in another member function of Actions).

The reason is you need an object instance to call a pointer-to-member function, so you don't explicitly need a this if you have a valid object of an Actions (see main function):

#include <iostream>
#include <string>

class Actions{
private:
    int actionId;
    int stateId;
    int eventId;
public:
    typedef std::string (Actions::*functionPtr)(int previousState, int currentState, int eventId);
    static functionPtr _ptrAction1;

    Actions(int actionId, int stateId, int eventId)
    {
        this->actionId = actionId;
        this->stateId = stateId;
        this->eventId = eventId;
        Actions::_ptrAction1 = &Actions::function1;
    }
    int doAction(int act, int previousState, int currentState, int eventId);
    std::string function1(int previousState, int currentState, int eventId);
};

// linker
Actions::functionPtr Actions::_ptrAction1;

std::string Actions::function1(int previousState, int currentState, int eventId){
    return "this is an example for now";
}

int Actions::doAction(int act, int previousState, int currentState, int eventId)
{
    int functionId = 0;
    std::string message;

    switch(act){
       case 1:
           message = (this->*_ptrAction1)(previousState, currentState, eventId);
           break;
       default:
           break;
       }
}

int main(int argc, char* argv[])
{
    Actions* act = new Actions(1,2,3);
    // have to say Actions::_ptrAction1 since it's a static member, but
    // we still need a valid Actions object to act on (for the hidden this)
    std::cout << (act->*Actions::_ptrAction1)(3,2,1) << std::endl;
    delete act;
    return 0;
}

1 Comment

Thank you txtechhelp that is very helpful especially your explanation on re-declaration and * precedence. I will look to revise my code with your suggestions I'm afraid I don't have the rep to upvote otherwise I would do so! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.