调用C ++成员函数指针而不知道哪个类

时间:2017-08-14 20:21:31

标签: c++ pointer-to-member

我试图调用一个成员函数,可能给出了对象指针,而不知道成员函数来自哪个类。这可能吗?

基本上我想要像以下一样工作。

class Foo{
public:
    Foo(void* object): obj(object) {}

    void callFunc(void (*func)()){
        obj->*func();
    }

private:
    void* obj;
};

class Bar{
public:
    Bar(): foo(this) {}

    void callSomeFunc(){
        callFunc(someFunc);
    }

    void someFunc(){
        cout << "hi\n";
    }

private:
    Foo foo;
};

int main(){
    Bar bar;
    bar.callSomeFunc();
    return 0;
}

3 个答案:

答案 0 :(得分:4)

它看起来很像XY问题。无论如何,让我们试着回答你的问题。

函数成员绑定到它所属的类的类型,除非它是静态的(后者被视为普通的函数指针,你甚至不必通过一个指向要调用它的实例的指针。) 因此,您可以将callFunc设为功能模板,并让它为您推断出类型:

template<typename T>
void callFunc(void (T::*func)()){
    (static_cast<T*>(obj)->*func)();
}

wandbox上查看并运行。

请注意,如果static_cast obj void *原始类型(您将其删除以将其置于T中)并非#include<iostream> class Foo{ public: Foo(void* object): obj(object) {} template<typename T> void callFunc(void (T::*func)()){ (static_cast<T*>(obj)->*func)(); } private: void* obj; }; class Bar{ public: Bar(): foo(this) {} void callSomeFunc(){ foo.callFunc(&Bar::someFunc); } void someFunc(){ std::cout << "hi\n"; } private: Foo foo; }; int main(){ Bar bar; bar.callSomeFunc(); return 0; } ,则可能会出现错误1}}。

以下是您可以在上面的链接中看到的完整代码:

{ className: "newClassName" }

答案 1 :(得分:1)

这是一个XY问题。使用std::function和/或lambda。

#include <functional>
#include <iostream>

class Foo{
public:
    template<class F>
    void callFunc(F&& f){
        f();
    }
};

class Bar : public Foo{
public:
    Bar(): foo() {}

    void callSomeFunc(){
        this->callFunc([this]{ someFunc(); });
    }

    void someFunc(){
        std::cout << "hi\n";
    }

private:
    Foo foo;
};

int main(){
    Bar bar;
    bar.callSomeFunc();
    return 0;
}

答案 2 :(得分:0)

虽然我发现@skypjack提供的解决方案更加优雅,但这里有一个解决方案,可以模拟Foo - 类(不仅仅是“函数”)作为一个整体。因此obj类中Foo的类型是已知的,这可能是一个优势(或可能不是)。

此外,还请参阅将成员与关联对象一起存储的解决方案。也许它在某种程度上有所帮助:

#include <functional>
#include <iostream>


template<class T>
class Foo {
public:
    Foo(T& obj) : _obj(obj) {}

    void callFuncOnObj(void (T::*func)(void)) {
        auto fn = mem_fn(func);
        fn(_obj);
    }

private:
    T &_obj;
};

class Bar{
public:
    Bar() : d(*this) {}

    void callSomeFunc(){
        d.callFuncOnObj(&Bar::someFunc);
    }

    void someFunc(){
        cout << "hi Bar1\n";
    }

private:
    Foo<Bar> d;
};

class Foo2 {
public:
    Foo2(std::function<void(void)> f) : _f(f) {}

    void callFunction() {
        _f();
    }

private:
    std::function<void(void)> _f;
};

class Bar2{
public:
    Bar2() : d(std::bind(&Bar2::someFunc,this)) {}

    void callSomeFunc(){
        d.callFunction();
    }

    void someFunc(){
        cout << "hi Bar2\n";
    }

private:
    Foo2 d;
};


int main(){

    Bar bar;
    bar.callSomeFunc();

    Bar2 bar2;
    bar2.callSomeFunc();

    return 0;
}