3

I have a class Ghost that has an array of functions. This class Ghost is an array too. How do I call the functions in main? I cant find a way to call this functions. I have seen some examples but nothing like this.

class Ghost;

typedef void(Ghost::* Func)();

class Ghost
{
    public:
    Func func;

    public:

    void init() {};
    void running_random() {};
    void running_afraid() {};
    void dead() {};


    Ghost(){
        func = new Func[5];

        func[0] = &Ghost::init;
        func[1] = &Ghost::random;
        func[2] = &Ghost::running_afraid;
        func[4] = &Ghost::dead;
    }

};


int main()
{
    Ghost ph[4];

    ph[0]->*func[0](); //???
    ph[0]->(*func[0]()); //???
    (ph[0]->*func[0])(); //???
}
3
  • 2
    The one thing missing is the actual error you're receiving. Commented May 19, 2019 at 4:19
  • (ph[0].*ph[0].func[0])(); And btw, your Func func; is wrong. It should be Func *func; . Otherwise func = new Func[5]; is nonsense. Also broken, there is no Ghost::random. That should be Ghost::running_random. Commented May 19, 2019 at 4:25
  • @OP -- I would suggest a public member function that calls the function via pointer. void call_func(int num) { (this->*func[num])(); } -- Then it's just ph[0].call_func(0); in the main(). Is that an option, i.e. adding a member function that makes the call look more pleasant? Commented May 19, 2019 at 4:31

1 Answer 1

1

"I have a class Ghost that has an array of functions"

That isn't accurate. Those aren't just functions; they're pointers to member functions, which are distinct beasts unto their own.

Of the things wrong in this code.

  1. Func func should be Func *func;

The way you had it, Func func; declares a single pointer-to-member variable, and you clearly want an array of them.

  1. Wrong member-access operator.

You're using operator ->*, which should be used against a pointer to object married to a pointer to member. But you don't have a pointer to object. Given Ghost ph[4]; that means ph[0] is not Ghost*, it's Ghost. Therefore, operator .* should be used.

  1. Improper access to func member.

The array holding the pointers to members is a member of Ghost. Using the member access operators (operator .* or operator ->*) doesn't magically grant access to member func. That's just where you chose to store those member function pointers. Those operators don't behave like operator . and operator ->

  1. Incorrect object and member coupling.

When coupling a pointer-to-member with a concrete object using operator .* (or a pointer to object using operator ->*), the full expression of the coupling should be enclosed in parentheses, then the argument list should follow in its own parentheses. In short, only the last of these makes sense (but is still broken due to the plethora of problems above).

ph[0]->*func[0]();
ph[0]->(*func[0]());
(ph[0]->*func[0])(); // closest to correct

Summary

After all of that, we can craft something that will actually work:

#include <iostream>

class Ghost;
typedef void(Ghost::*Func)();

class Ghost
{
public:
    Func* func;

public:

    void init() {std::cout << "here!!\n"; };
    void running_random() {};
    void running_afraid() {};
    void dead() {};

    Ghost(){
        func = new Func[5];

        func[0] = &Ghost::init;
        func[1] = &Ghost::running_random;
        func[2] = &Ghost::running_afraid;
        func[4] = &Ghost::dead;
    }
};


int main()
{
    Ghost ph[4];

    (ph[0].*ph[0].func[0])();
}

Output

here!!

I leave the ensuing memory leaks and realization this is probably not the architecture you really wanted in the first place for you to handle. But those were the problem, and a resolution, to the code you posted.

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

Comments

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.