指向类的指针和指向方法的指针

时间:2015-05-23 09:45:27

标签: c++ member-function-pointers

如何制作指向类和成员函数的双指针?

基本上,我有一些(很多)泛型类接受像这样的函数指针:

void Gen::regCallback(void (*callback)(void const *), void const * callbackData)

在课堂上,我经常有这样的功能

void Foo::doSomething(void const * instance) // this one is static
{
    auto myself((Foo const *)instance);
    myself->...do stuff...
    myself->...do stuff...
    myself->...do stuff...
}

或方法/功能双胞胎

void Foo::doSomething(void const * instance) // this one is static
{
    ((Foo const *)instance)->doSomething();
}
void Foo::doSomething() const
{
    ...do stuff...
    ...do stuff...
    ...do stuff...
}

我想以某种方式减少代码中的混乱(通过直接注册成员), 我知道选项:

void Gen::regCallback(void (Foo::*callback)(void const *), Foo const * member);

但我需要将类型(Foo)作为参数传递(即Foo1,Foo2,FooTotallyDifferent)

由于各种原因,我不能将模板用于类类型,所以

template <typedef T>
class Gen
{
    void regCallback(void (T::*callback)(void const *), T const * member)
    {
        ...
    }
}

对我来说是没有选择

1 个答案:

答案 0 :(得分:1)

看起来你想要的是能够注册任何可调用的,它接受零参数并返回void。由于您可能会将这些回调存储在某个地方,因此您还需要类型擦除 - 因为您希望能够非常地调用doSomethingElse()Bar::someMethod(with, some, args)甚至std::function<void()>。对于所有这些以及更多,有std::function。特别是在您的情况下,std::function<void()>

用法很简单。可以从与该签名匹配的任何函数构造std::function。下面是一个示例,它将几种不同的可调用类型添加到一个using Callback = std::function<void()>; std::vector<Callback> callbacks; void free() { std::cout << "free\n"; } void free(int arg) { std::cout << "free " << arg << "\n"; } struct Foo { void something() const { std::cout << "Foo with " << i << "\n"; } int i; }; callbacks.emplace_back(free); // normal function pointer Foo f; callbacks.emplace_back(std::bind(&Foo::something, f)); // member function bound to instance, copies f callbacks.emplace_back([]{ free(42); }); // lambda calling function with specific argument f.i = 64; callbacks.emplace_back([&]{ f.something(); }); // captures f f.i = 72; // call all of them for (auto fn : callbacks) { fn(); } 类型的向量中:

free
Foo with 42
free 42
Foo with 72

那将打印

{{1}}