指向方法父参数c++的子类方法指针

child class method pointer to method parent argument c++

本文关键字:类方法 指针 c++ 参数 方法      更新时间:2023-10-16

我想看到的可能很奇怪,我会尽可能多地澄清。我在ubuntu 14.04和C++11上使用的是gcc 4.8。

我想尝试做的是:

  • 取得a级成绩
  • 在类a中生成一个函数作为参数
  • 指向同一类的类成员的指针
  • 创建一个继承自a的新类B
  • 制作B类的新方法
  • 将指向B类方法的指针指定给父类a的方法作为参数

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

然而,这给我带来了以下代码块错误:

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

有办法解决这个问题吗?我还有什么需要做的吗,让你明白我正在努力实现的目标?

不能直接从基类调用子方法,但可以使用模板:

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

但更灵活的解决方案是使用std::functionstd::bind,因为这样您就可以传递签名不匹配的方法。

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

问题是sampleMethod不是A的成员,它是B的成员,无法转换为void(A::*)

你是否考虑过使用虚拟方法?

typedef void(A::*METHOD);        

METHOD定义为指向A的成员变量的void*类型的指针,而不是指向A的成员函数的指针。

您需要:

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

即使进行了更改,也不能使用B的成员函数作为参数传递METHOD

您可以制作想要传递A的虚拟成员函数的函数并使用它

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

要使一个可调用对象绑定到一个成员函数,您应该使用std::bind。这将创建一个转发包装器,该包装器将使用预先指定的一些参数来调用sampleMethod。在这种情况下,"this"参数将被绑定。

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