Search code examples
c++classfunction-pointers

Function pointers on a class's member function


void Parser::add_func_no_arg(void (Virtual_Machine::*f)(), std::string comand)
{
    command_no_arg.push_back(comand);
    func_no_arg.push_back(f);
}

void Parser::prepare()
{
    //add_func_no_arg(Virtual_Machine::dump,"dump"); it work when i put it in static but i cant do that
    add_func_no_arg(vm.clear,"clear"); // ERROR HERE the vm.clear does not fit
}

I have those two functions to try help my create a array of pointers func_no_arg; I can't put the vm's func in static; Why cant i have a pointer on a function when it is "trap" whit in one objet ? maybe the type is wrong, here is some .hpp :

class Parser {
    public:
       /***/
        void prepare();
        void add_func_no_arg(void (Virtual_Machine::*f)(), std::string comand);

    private:
        Virtual_Machine vm;
        std::vector<std::string> command_no_arg;
        std::vector<void (Virtual_Machine::*)()> func_no_arg;
        /***/

};


class Virtual_Machine {
    public:
      /***/
        void clear();
      /***/
}

and the compiler said this :

Parser.cpp: In member function ‘void Parser::prepare()’:
Parser.cpp:65:36: error: invalid use of non-static member function ‘void Virtual_Machine::clear()’
     add_func_no_arg(vm.clear,"dump");
                                    ^
In file included from ../include/Parser.hpp:13,
                 from Parser.cpp:8:
../include/VM.hpp:23:14: note: declared here
         void clear();

Solution

  • As written by IlCapitano you have to use a specific syntax to deal with pointer-to-members. Here is an example (compiled with g++ tmp.cpp -o tmp):

    #include <iostream>
    #include <string>
    #include <vector>
    
    class Virtual_Machine
    {
        private:
            std::string name;
    
        public:
            Virtual_Machine(std::string n) : name(n) {}
            void clear() { std::cout << "Clear " << name << std::endl; }
    };
    
    class Parser
    {
        private:
            Virtual_Machine vm;
            std::vector<std::string> command_no_arg;
            std::vector<void (Virtual_Machine::*)()> func_no_arg;
    
        public:
            Parser(std::string vm_name) : vm(vm_name) {}
            void add_func_no_arg(void (Virtual_Machine::* f)(), std::string command)
            {
                command_no_arg.push_back(command);
                func_no_arg.push_back(f);
            }
            void prepare()
            {
                add_func_no_arg(&Virtual_Machine::clear, "clear");
            }
            void test()
            {
                (vm.*(func_no_arg[0]))();
            }
    };
    
    int main()
    {
        Parser a("vm_a"), b("vm_b");
    
        a.prepare();
        b.prepare();
    
        a.test();
        b.test();
    
        return 0;
    }
    

    The output of the program is:

    Clear vm_a
    Clear vm_b
    

    A pointer to the member function clear of an instance of class Virtual_Machine is created with &Virtual_Machine::clear. To later call this function you have to use the operators .* or ->* with an instance of the class on the left side of the operator and the pointer to the function on the right side, like (vm.*(func_no_arg[0]))(). If the function would have parameters, you would place them in the most right pair of parentheses.