1

I have a situation very similar to this question but the way I need to call the Member Function is slightly different and can not figure it out. What I have is a vector that contains commands to execute within a class. What I need to do is assign a member pointer to a member of the same class AND call it within the class. So in other words I have a class that will create a series of commands that are put into a vector array and call the Member Function. I need to do it this way so I can pre-initialize and configure the commands.

MotionCmd


class MotionManager;

struct MotionCmd{
   int id;
   int move;
   void (MotionManager::*funcPtr)() = NULL;
}

MotionManager


class MotionManager{
   std::vector<MotionCmd> stack;

   void ConfigureCmd(int id, int move){
       MotionCmd cmd;

        /* Configure the Cmd */

       //This is the only way I can get the assignment is there a way to use 'this->'?
       cmd.funcPtr = &MotionManager::LinearMove;
       stack.push_back(cmd);
   }

   void Update(){
      //This is another area I am having problems

      //Doesn't work Error: "must use '.*' or '->*' to call pointer ...
      this->*(this->stack[0].funcPtr)(); 

      //Nope: Error: functPtr was not declared in this scope
      this->(cmd.*funcPtr)();

      //This doesn't either Error: functPtr was not declared in this scope
      this.stack[0].*funcPtr();

      //This either Error: functPtr was not declared in this scope
      (this->stack[0].*funcPtr)();

      //Error: must use '.*' or '->*' to call pointer....
      ((*this)->*(this->stack[0].funcPtr()))();

   }

   void LinearMove(){
       /* Perform Move */
   }
}

I hope this can be done this way I am just not sure what the syntax needs to be. I have read countless articles on this but nothing that uses a pointer quite like this. Please keep in mind that this is running on a Mega2560 and anything other than the std::vector from the stdlib is not really an option since vector is one of the only parts I can get to work from the StandardCPlusPlus library.

I did also try to make the function Static but I received an error that the linker could not make the function static. Something about can't convert void() to void(MotionManager::)...

Edit


JasonC and antipattern got me on the right track. It was indeed the way I was trying to get ahold of the MotionManager class using 'this'. Like antipattern pointed out "the implicit this-pointer which is the first argument to any member function". So I thought about that for a minute and realized how to get things working the code should read like:

MotionManager


class MotionManager{
   std::vector<MotionCmd> stack;

   void ConfigureCmd(int id, int move){
       MotionCmd cmd;

        /* Configure the Cmd */

       //This is the only way I can get the assignment is there a way to use 'this->'?
       cmd.funcPtr = &MotionManager::LinearMove;
       stack.push_back(cmd);
   }

   void Update(){

      //Call the Member Function using 'this'...
      (this->*(this->stack[0].funcPtr))();

   }

   void LinearMove(){
       /* Perform Move */
   }
}

Thanks again guys I hope this helps someone else out... Function Pointers can be a messy business, use with caution...

Community
  • 1
  • 1
Andy Braham
  • 9,594
  • 4
  • 48
  • 56
  • I'm on my phone hard to answer and I'm sure you'll get a good one. But some alternate design ideas to think about: - store a MotionManager* in MotionCommand and call its members directly. Or: - let MotionManager handle MotionCmds, move update to MotipnManager, put logic there. Etc. I feel like maybe 85% of the time pointers to members come to the party it ends up being a better case for polymorphism and moving code around. Hope that made sense, touch keyboards are a step backwards in technology... – Jason C Nov 24 '16 at 14:58
  • 2
    Looks like your issue is the implicit this-pointer which is the first argument to any member function. I haven't been using AVR recently, so I can't tell if they support c++11, if they do, you should have a look at std::bind. It can be used to implement function pointers to member functions. I haven't yet come across any other way to do that (but I haven't looked too much either) – antipattern Nov 24 '16 at 14:58
  • @JasonC If I store a MotionManager inside the MotionCmd then I would have 2 instances of the MotionManager wouldn't I? That seems like it would gobble up memory. Also I do have the Update() within the MotionManager, I am trying to keep everything inside the MotionManager if I can... – Andy Braham Nov 24 '16 at 15:09
  • @andy One instance. Pointers. – Jason C Nov 24 '16 at 22:36

0 Answers0