philsegeler
philsegeler

Reputation: 163

child class method pointer to method parent argument c++

it might be strange what i'm trying to see and i will try to clarify as much as possible. I'm using gcc 4.8 on ubuntu 14.04 and C++11.

What i want trying to do is:

However this brings me the following error in codeblocks:

error: no matching function to call for 'B::executeMethod(void B::*)'

Is there any way around this? Is there anything else i need to do to make it clear to you, what i'm trying to accomplish?

Upvotes: 3

Views: 1275

Answers (4)

Slava
Slava

Reputation: 44248

You cannot directly call child method from a base class, but you can use template:

class A {
public:
    template<class T>
    void executeMethod( void (T::*method)() )
    {
        (static_cast<T *>( this )->*method)();
    }
};

class B : public A {
public:
    void sampleMethod() {}
    void childMethod() { executeMethod( &B::sampleMethod ); }
};

But more flexible solution would be to use std::function and std::bind as then you can pass methods which signature does not match.

class A {
public:
    typedef std::function<void()> Method;

    void executeMethod( const Method &method )
    {
        method();
    }
};

class B : public A {
public:
    void sampleMethod1() {}
    void sampleMethod2( int param ) {}

    void childMethod1() { executeMethod( std::bind( &B::sampleMethod1, this ); }
    void childMethod2() { executeMethod( std::bind( &B::sampleMethod2, this, 123 ); }
};

Upvotes: 2

Wayne Tanner
Wayne Tanner

Reputation: 1356

To make a callable object bound to a member function you should use std::bind. This will create a forwarding wrapper which will call sampleMethod with some of its parameters pre specified. In this case, the "this" parameter will be bound.

std::bind(&B::sampleMethod, this);

Upvotes: 1

R Sahu
R Sahu

Reputation: 206577

typedef void(A::*METHOD);        

defines METHOD to be a pointer of type void* to a member variable of A, not a pointer to a member function of A.

You need:

typedef void (A::*METHOD)();        

Even with that change, you can't use a member function of B to pass as an argument where METHOD is expected.

You can make the function that you want to pass a virtual member function of A and use it.

class A {
   protected:
      typedef void(A::*METHOD)();        

      void executeMethod(METHOD arg){};

   public:
      virtual void sampleMethod() = 0;
};

class B : public A {

   virtual void sampleMethod(){};

   void childMethod(){              

      this->executeMethod(&A::sampleMethod);
   }
};

Upvotes: 2

Mark B
Mark B

Reputation: 96241

The problem is that sampleMethod isn't a member of A, it's a member of B and can't convert to a void(A::*).

Did you consider using virtual methods perhaps?

Upvotes: 2

Related Questions