child class method pointer to method parent argume

2019-01-28 07:18发布

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:

  • make a class A
  • make a function in that class A which gets as argument
  • a pointer to a class member of the same class
  • make a new class B which inherits from A
  • make a new method of class B
  • give a pointer to that method of class B to a method of parentclass A as argument

    class A{
        typedef void(A::*METHOD);        
    
        void executeMethod(METHOD arg){};
    }
    
    class B : A{
    
        void sampleMethod(){};
    
        void childMethod(){              
    
          this->executeMethod(&B::sampleMethod); //<== error
        }
    }
    

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?

4条回答
Bombasti
2楼-- · 2019-01-28 07:47
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);
   }
};
查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-01-28 07:51

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?

查看更多
beautiful°
4楼-- · 2019-01-28 07:56

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 ); }
};
查看更多
爱情/是我丢掉的垃圾
5楼-- · 2019-01-28 07:57

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);

查看更多
登录 后发表回答