child class 指向方法父参数 c++ 的方法指针
child class method pointer to method parent argument c++
我想看到的东西可能很奇怪,我会尽量澄清。我在 ubuntu 14.04 和 C++11 上使用 gcc 4.8。
我想尝试做的是:
- 做一个class一个
- 在那个 class A 中创建一个函数,它作为参数
- 指向同一 class
的 class 成员的指针
- 创建一个继承自 A
的新 class B
- 制作class B
的新方法
将指向 class B 的方法的指针指向父class 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::*)'
有什么办法解决这个问题吗?
我还需要做些什么来向您说明我正在努力实现的目标吗?
问题是 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, 这个);
您不能直接从基础 class 调用子方法,但您可以使用模板:
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::function
和 std::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 ); }
};
我想看到的东西可能很奇怪,我会尽量澄清。我在 ubuntu 14.04 和 C++11 上使用 gcc 4.8。
我想尝试做的是:
- 做一个class一个
- 在那个 class A 中创建一个函数,它作为参数
- 指向同一 class 的 class 成员的指针
- 创建一个继承自 A 的新 class B
- 制作class B 的新方法
将指向 class B 的方法的指针指向父class 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::*)'
有什么办法解决这个问题吗? 我还需要做些什么来向您说明我正在努力实现的目标吗?
问题是 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, 这个);
您不能直接从基础 class 调用子方法,但您可以使用模板:
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::function
和 std::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 ); }
};