Chris
Chris

Reputation: 4525

unable to pass a pointer to a function between classes

I'm attempting to pass a pointer to a function that is defined in one class into another class. After much research, I believe my syntax is correct, but I am still getting compiler errors. Here is some code which demonstrates my issue:

class Base
{
public:
    BaseClass();
    virtual ~BaseClass();
};

class Derived : public Base
{
public:
    // assign strFunction to the function pointer passed in
    Derived(string (*funPtr)(int)) : strFunction(funPtr);
    ~Derived();

private:
    // pointer to the function that is passed in
    string (*strFunction)(int value);
};

class MainClass
{
public:
    MainClass()
    {
        // allocate a new Derived class and pass it a pointer to myFunction
        Base* myClass = new Derived(&MainClass::myFunction);    
    }

    string myFunction(int value)
    {
        // return a string
    }
};

When I try to compile this code, the error I get is

error: no matching function for call to 'Derived::Derived(string (MainClass::*)(int))'

followed by

note: candidates are: Derived::Derived(string (*)(int))

Any idea what I might be doing wrong?

Upvotes: 6

Views: 1950

Answers (9)

Evan Teran
Evan Teran

Reputation: 90432

your syntax is correct for a C style function pointer. Change it to this:

Derived(string (MainClass::*funPtr)(int)) : strFunction(funPtr) {}

and

string (MainClass::*strFunction)(int value);

remember to call strFunction, you will need an instance of a MainClass object. Often I find it useful to use typedefs.

typedef string (MainClass::*func_t)(int);
func_t strFunction;

and

Derived(func_t funPtr) : strFunction(funPtr) {}

Upvotes: 8

bsruth
bsruth

Reputation: 5502

You may want to look into using std::tr1::bind and std::tr1::function similar to this (untested) code:

class Derived: public Base
{
  public:
    typedef std::tr1::function<string(int)> StringFunc;

    Derived(StringFunc);

  ...

  private:
    StringFunc strFunction;
}

and in MainClass constructor:

myBase = new Derived(std::tr1::bind(&MainClass::myFunction, *this, _1);

The bind function basically binds the member function to a particular object. Which takes care of the this pointer that is inserted by the compiler.

Upvotes: 1

lsalamon
lsalamon

Reputation: 8174

Another syntax issue :


    // assign strFunction to the function pointer passed in
    Derived(string (*funPtr)(int)) : strFunction(funPtr);

replace for :


    // assign strFunction to the function pointer passed in
    Derived(string (*funPtr)(int)) : strFunction(funPtr) {};

Upvotes: 2

Crashworks
Crashworks

Reputation: 41394

You can learn more about the grave wickedness that is C++ member function pointer syntax here.

Upvotes: 5

Eclipse
Eclipse

Reputation: 45493

As the compiler warning is indicating, member function pointers are completely different from regular function pointers.

Upvotes: 0

Tom Smith
Tom Smith

Reputation: 1659

You are trying to pass a pointer to a member function of the class MainClass, but the function expects a pointer to an ordinary, ie non-member, function. A good summary is here

The difference is important because member functions have a hidden extra parameter which tells the function which "this" pointer to apply the function to. So the pointer types aren't interchangeable.

Upvotes: 4

CB Bailey
CB Bailey

Reputation: 791869

Yes, the type of &MainClass::myFunction is a pointer-to-member type whereas string(*)(int) is a pointer-to-function type. They are not compatible as you have to use a reference or pointer to a class instance and use the .* or ->* operators to use a pointer-to-member, whereas a pointer to a function is not attached to a class and can be called directly.

Upvotes: 4

Function pointers (that is pointers to unbound functions) and pointers-to-methods (that is pointers to non-static functions bound to a class definition), are different in c++. This is because non-static methods have an implicit this argument which requires that they always be called in the context of a instance of their class.

You're trying to pass a method-pointer to a constructor that takes a function-pointer. Which won't work.

Upvotes: 2

Paul Tomblin
Paul Tomblin

Reputation: 182782

Object methods have a hidden "this" argument. If you pass the method to another class, what gets filled into the "this" argument? You might be able to do it with static (Class) methods.

Upvotes: 0

Related Questions