无法将指向派生类函数的指针传递给基类

Posted

技术标签:

【中文标题】无法将指向派生类函数的指针传递给基类【英文标题】:Can't pass pointer to derived class function into base class 【发布时间】:2012-01-10 13:07:49 【问题描述】:

我正在尝试将派生类中的函数传递给需要函数指针的基类函数,但出现编译器错误。

[BCC32 Error] E2034 Cannot convert 'void (Bar::*)(int)' to 'void (Foo::*)(int)'

我想这是按设计的,但是有没有一种不涉及不愉快的铸造的方法? boost::bind可以帮我吗?

#define CALL_MEMBER_FN(object,ptrToMember)  ((object).*(ptrToMember))

class Foo

public:
  typedef void (Foo::*FFunc)(int i);

  void test(FFunc f)
  
    CALL_MEMBER_FN(*this,f)(123);
  

  void barf1(int i) ;
;

class Bar : public Foo

public:
  void barf2(int i) ;
;

void ffff()

  Foo f;
  f.test(Foo::barf1); // works

  Bar b;
  b.test(Bar::barf1); // works
  b.test(Bar::barf2); // ERROR

作为旁注,我使用虚函数可以正常工作,这是显而易见的方法,而不是函数指针,但我只是想让它以这种方式工作,然后再尝试一些 boost::bind 技巧...

【问题讨论】:

如果你有 C++11 编译器,也许你可以使用 std::functionstd::bind 【参考方案1】:

b.test( ( Foo::FFunc )&Bar::barf2 );

对不起,不是要提交它作为答案,想发表评论。 Sample code.

编辑:嗯,也许这是更“令人愉快”的铸造,因为它是 C++ 风格? Updated sample.

b.test( static_cast< Foo::FFunc >(&Bar::barf2) );

【讨论】:

嗯,是的,这行得通。但这是我希望避免的那种“不愉快的演员阵容”! @Roddy 您可以使用static_cast,这是完全有效的 C++ 演员表。我的意思是,我打赌boost::bind 在内部某处使用了这样的铸造东西...... 你确定这是有效的 c++ 吗?从我记得将函数(或成员函数)指针转换为不同类型然后尝试调用它是非法的。在这种情况下它可能会起作用,因为从bFoo* 的转换(当调用test 时)可能是一个问题,但我认为这不能保证(如果涉及多重继承或虚拟继承,则不会工作) )。 @Grizzly 调用test 时,没有从Bar*Foo* 的转换。 testBar 的成员...我称之为“有效的 C++ 演员表”的东西是 static_cast 在具有相同签名的函数上。如果你声明void barf2( float); 编译器不会让你static_cast 它。【参考方案2】:

另外,由于我对 c++11 && bost && stl 的了解不是最好的,我只能建议:

 template <typename T>
    void test(void (T::*f)(int))
  
    CALL_MEMBER_FN(static_cast<T&>(*this),f)(123);
  

所有其他代码与您的相同。

错误的投射,但它被隐藏了

【讨论】:

【参考方案3】:

你能概括一下函数指针吗?我的意思是这样的:

typedef void (Foo::*FFunc)(int i);

到:

typedef void (*FFunc)(int i);

然后就可以使用bind了:

b.test(bind(&Bar::barf2, &b));

【讨论】:

不,你不能因为bind(我假设你的意思是boost::bindstd::bind,否则请详细说明)返回一个函子对象而不是函数指针。 typedef function&lt;void(int)&gt; FFunc; 应该可以工作(但当然会有很多开销)。 ` 你是对的,我的错。我使用 boost:function,而不是函数指针。 bind 不适用于指针。

以上是关于无法将指向派生类函数的指针传递给基类的主要内容,如果未能解决你的问题,请参考以下文章

C++继承,发送一个指向基类的指针

在 C++ 中将指向基类的指针传递给派生类的成员函数

将派生类引用传递给基类引用

将派生类传递给基类参数的函数

试图将派生类对象地址分配给基类指针向量

最佳实践:将派生类的向量传递给基类向量上的方法