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

问题描述:

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

基本上我想要类似下面的工作。

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; 
} 
+1

您可以通过将成员函数封装在静态适配器中来实现:http://ideone.com/I4dH4b。但我不确定这很有用。 – melpomene

+0

你究竟想要做什么?你想要解决的具体任务是什么?你的程序不适合C++范例 – LmTinyToon

+2

你可能对'std :: function'感兴趣。 –

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

函数成员绑定到它所属的类的类型,除非它是静态的(后者被视为一个普通的函数指针,并且您甚至不必将指针传递给实例称它)。
因此,你可以让callFunc一个函数模板,让它推断类型为您提供:

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

见它,并在wandbox运行。

注意,您可以在错误招致当你static_castobj如果原始类型(你擦除把它放在一个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; 
} 
+0

我想我必须以某种方式使用模板。虽然这比将所有Foo模板化为我想要的更简单。 –

+0

跟进问题。如果我需要将该函数存储在成员变量中,是否需要模板整个类(在本例中为Foo)。 –

+0

@Bennett Bernardoni“如果我需要将函数存储在成员变量中”; '的std :: function'。 –

这是一个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; 
} 

虽然我发现模板的Foo -class(不是“唯一”的功能)作为一个整体通过@skypjack更优雅,这里的解决方案所提供的解决方案。因此,在整个Foo级别中,obj的类型是已知的,这可能是一个优点(或可能不是)。

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

#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; 
}