重新解释成员函数指针是个“好主意”吗?

时间:2009-10-15 14:53:00

标签: c++ member-function-pointers reinterpret-cast

我有一个工作线程,它包含一个“线程操作”列表,并作为一个时间通过它们。

template <class T> class ThreadAction
{
public:

  typedef void (T::*action)();

  ThreadAction(T* t, action f) :
    func(f),obj(t) {}
  void operator()() { (obj->*func)(); }

  void (T::*func)();
  T* obj;

};

它通常被称为

myActionThread->addAction(
    new ThreadAction<TheirClass>(this, &TheirClass::enable)
);

直到

才能正常工作
 void TheirClass::enable()

已更改为

 bool TheirClass::enable()

遗憾的是,我们无法再将其更改回来,因为其他内容需要新的格式(并且过载不能仅因返回类型而有所不同)。

我确实尝试了

myActionThread->addAction( 
    new ThreadAction<TheirClass>(this, 
        reinterpret_cast<void(TheirClass::*)>(&TheirClass::enable)
    )
);

哪个似乎工作正常,但我不确定重新解释像这样的函数指针是'已定义'的行为,有人可以建议吗?

4 个答案:

答案 0 :(得分:9)

这绝对是 not 支持的行为,并且可能会导致程序崩溃。

基本上,您需要为TheirClass::enable()创建一个具有正确返回类型的包装器。一个简单的单行就足够了:

public:
    void enableWrapper() { enable(); };

然后致电:

myActionThread->addAction(
    new ThreadAction<TheirClass>(this, &TheirClass::enableWrapper)
);

如果你不能直接修改TheirClass,那么创建一个实现包装器的简单子类或辅助类。

答案 1 :(得分:2)

呃,根据我的理解,你是从一个返回bool的方法转换为返回void的方法吗?

这可能很危险,具体取决于使用的调用/返回约定。您可能忘记弹出返回值 - 或使用返回值覆盖寄存器的值。

答案 2 :(得分:2)

不是个好主意。请考虑为返回类型添加其他模板参数:

template <class T, typename RetType> class ThreadAction
{
public:
 typedef RetType (T::*action)();
 ThreadAction(T* t, action f) :
   func(f),obj(t) {}

 RetType operator()() { return (obj->*func)(); }
 RetType (T::*func)();
 T* obj;
};

这是return void的应用程序。

答案 3 :(得分:1)

我通常会发现问题的形式是“_______是个好主意吗?”答案几乎总是“不!”

如果没有上下文,这可能是正确的。