Search code examples
c++static-functions

Set reference of function to non-static function from other c++ file


I'm trying to set a reference of a non-static function in c++. The function I'm referencing is not from the same c++ file, and I get and error saying :

Cannot create a non-constant pointer to member function.

Main.cpp

#include <iostream>
#include "Test.hpp"

class testClass {
public:
    void (*update) (void);
};

int main() {
    testClass tc;
    test t;
    tc.update = &t.update; //This is where the error occurs
    return 0;
}

Test.hpp

#ifndef Test_hpp
#define Test_hpp

#include <stdio.h>

class test {
public:
    void update() {
        //Do something
    }
};

#endif /* Test_hpp */

My question is how do you do this without setting update in test class to static?

static void update() {
    //Do something
}

Using this code it works, but like I've stated I do not want this functiont to be static.

EDIT : Because I'm stupid I failed to mention that the class test should be able to be different. Also to the answers I got already I learned that tc.update = &t.update; is wrong.

For Example :

#include <iostream>
#include "Test.hpp"
#include "anotherTestClass.hpp"

//I do not want to use templates if possible
class testClass {
public:
    void (*update)(void);
};

int main() {
    testClass tc;
    test t;
    tc.update = &test.update; //I know this is wrong now.
    testClass tc2;
    anotherTestClass atc;
    tc2.update = &atc.update;
    //p.s. I'm bad with c++
}

And the error i get now is.

Assigned to 'void (*)()' from incompatible type 'void (test::*)()'

One more thing is I'm using XCode to program, which I believe uses LLVM-GCC 4.2 as the compiler.


Solution

  • Your approach is essentially wrong.

    Member Function Pointers.

    The member in the testClass:

    void (*update) (void);
    

    is a function pointer, which is different to a method function pointer. That why in order to compile you should switch to a static method (which is essentially a "normal" function).

    A method function pointer should containt the static information about the class the method belongs.

    Practically the right way is:

    void (test::* ptr_method)(void);  // a member pointer to test class
    

    In that way the variable named ptr_method is a method of the class test pointer.

    Then,

    Get the Address of a method.

    Your statement:

    tc.update = &t.update; //This is where the error occurs
    

    is simply wrong. The address of a class method is something which is not related with the object of that class.

    You can obtain the address of a method with the syntax:

    &CLASS_NAME::METHOD_NAME;
    

    Indeed, that statement should be something like:

    tc.update = &test::update;
    

    Additional suggestions.

    Call a method by means of a method pointer.

    Once you have a method pointer it is not so immediate to call the method associated with it. As I said before, the address of the method is not related with the object of that class, so if you want to call the method you need to provide to the compiler the information about the object on which the method has to be called.

    The syntax is something like:

    (OBJECT.*METHOD_POINTER)(ARGS...);
    

    Here, I propose a simple demo which shows all what I've just said.