如何从静态成员函数调用指向成员函数的指针
How to invoke pointer to member function from static member function?
我需要获取一个由标准函数指针调用的成员函数,所以我尝试抽象如下:
class Sample {
public:
virtual void doSomething(void) = 0;
};
class A : public Sample {
void doSomething(void); // details omitted
};
class B : public Sample {
void doSomething(void); // details omitted
};
class Executor {
public:
Executor(Sample *sample)
: func(&sample->doSomething)
{
}
static void *execute(void *data) {
Executor *pX = data;
(pX->*func)(); // error invalid access of func from static function
(pX->*pX->func)(); // error pointer to member type 'void (Sample::)()'
// incompatible with object type 'Executor'
}
private:
void (Sample::*func)(void);
};
int main(void) {
A myA;
B myB;
Executor x0(&myA);
Executor x1(&myB);
externallyInvoke(&Executor::execute, &x0);
externallyInvoke(&Executor::execute, &x1);
}
externallyInvoke
是一个 Linux 系统调用,它接受一个函数指针和一个数据指针。我想将静态成员函数与 this 指针一起使用作为数据。
。而且我不希望像A
或B
这样的类有静态成员。所以我的想法是创建一个像类Sample
这样的接口,它通过A
和B
进行扩展。
我的问题是我不知道如何从Executor::execute
函数内部调用指向成员函数的指针。
问题是execute
里面需要两个对象 - 一个是将提供func
的Executor
实例,另一个是将调用func
的(派生自(Sample
的实例。所以你必须将对象存储在 Executor
中,而不是函数中:
class Executor {
public:
Executor(Sample *sample)
: obj(sample)
{
}
static void *execute(void *data) {
Executor *pX = static_cast<Executor*>(data);
pX->obj->doSomething();
}
private:
Sample *obj;
};
int main() { // note that `void main()` is not legal C++
A myA;
B myB;
Executor x0(&myA);
Executor x1(&myB);
externallyInvoke(&Executor::execute, &x0);
externallyInvoke(&Executor::execute, &x1);
}
指向成员函数的指针(例如原始void (Sample::*func)()
(标识类中的函数,但不存储对象。您仍然需要提供一个来调用该函数。
如果你想与外部系统调用进行交互,你基本上必须自己重新发明std::function
。没问题,在Stack Overflow,我们是重塑现有技术的主人。所以。。。
一、界面:
struct FunctionStateBase
{
virtual ~FunctionStateBase() {}
virtual void Invoke() = 0;
};
extern "C" void InvokeAndDelete(void * data)
{
auto state = static_cast<FunctionStateBase *>(data);
state->Invoke();
delete state;
}
以下是您的使用方法:
externallyInvoke(&InvokeAndDelete, MakeFunction(&A::doSomething, &myA));
现在我们需要实现MakeFunction
:
template <typename> struct FunctionState;
template <typename C, typename R>
struct FunctionState<R (C::*)()> : FunctionStateBase
{
R (C::ptmf_*)();
C * obj_;
FunctionState(R (C::ptmf*)(), C * obj) : obj_(obj), ptmf_(ptmf) {}
virtual void Invoke() { (C->ptmf_)(); }
};
template <typename C, typename R>
FunctionState<R (C::*)()> MakeFunction(R (C::*ptmf)(), C * obj)
{
return new FunctionState<R (C::*)()>(ptfm, obj);
}
此时,我们正在手动管理函数包装器的生命周期,并注意InvokeAndDelete
实际上拥有函数状态的所有权。在适当的C++中,我们将整个系统调用调用包装在一个类中,该类将在内部封装生命周期管理。
您可以为接受参数的成员函数添加进一步的专用化;您只需要在状态中存储参数的副本。
您还需要传递一个Sample
实例来调用该函数(因为它是指向 Sample
成员的指针(。有几种方法可以引入实例。你可以让它成为 Executor
的成员,将std::pair*
作为data
传递,或者你可以将函数指针和实例组合为函子。这是针对后者的基于lamda的方法。耐磨达的优点是用途更广。可以做的不仅仅是调用一个类的一个成员。作为奖励,这种方法不会避免可见性规则,尽管这意味着doSomething
可能不是私有的(或者必须通过父指针调用(。
template<class F>
class Executor {
F f;
public:
Executor(F f): f(f){}
static void *execute(void *data) {
Executor<F> *pX = static_cast<Executor<F>*>(data);
pX->f();
return this; // not quite sure what you intend to return, but just to make this a well formed function...
}
};
int main() {
A myA;
B myB;
auto callback0 = [myA]{
myA.doSomething();
};
auto callback1 = [myB]{
myB.doSomething();
};
Executor<decltype(callback0)> x0(callback0);
Executor<decltype(callback1)> x1(callback1);
externallyInvoke(&Executor::execute, &x0);
externallyInvoke(&Executor::execute, &x1);
}
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 将公共但非静态的成员函数与ALGLIB集成
- 使用指向成员的指针将成员函数作为参数传递
- 将重载的成员函数传递给函数模板
- 我不小心调用了一个没有自己类对象的成员函数.但这是怎么回事呢
- 如何在C++中使用非静态成员函数作为回调函数
- C++错误C2600:无法定义编译器生成的特殊成员函数(必须首先在类中声明)
- 关联容器的下界复杂性:成员函数与非成员函数
- 在 C++ 中用派生类型重写成员函数
- 链表的泛型函数remove()与成员函数remove)
- 如何将lambda作为模板类的成员函数参数
- constexpr构造函数需要常量成员函数时出现问题
- 将自由函数绑定为类成员函数
- 区分非成员函数和头文件中的成员函数
- 如何从子成员函数修改父公共成员变量
- 保留对其他类的成员函数的引用
- 在运算符重载定义中使用成员函数(const错误)
- 内联如何影响模块接口中的成员函数
- 将成员函数指针作为参数传递给模板方法