您可以使用如下声明创建一个指向成员函数的 pre C++11 函数指针:
ReturnType (ClassType::*func_ptr)() = &ClassType::function;
并使用带有(instance.*func_ptr)() 的类的一个实例 调用它。例如
struct Foo {
bool memberFunc() { return true; }
};
int main() {
typedef bool (Foo::*member_func_t)(); // Typedef member func pointer type.
member_func_t func_ptr = &Foo::memberFunc; // Declare function pointer.
Foo foo; // Create foo object.
(foo.*func_ptr)(); // Call member func using instance.
}
如果您只需要创建指向成员函数的指针,有一种方法可以重新创建您正在寻找的通用属性 (I read your other question too)。如果你混入非成员函数指针,它将不起作用。
通过使用模板和派生自通用非模板基类的包装类,您可以包装一个指向任何类类型成员的函数的成员函数指针。基类创建一个公共类型,独立于包装函数指针是哪个类的成员。如果您例如,这可能很有用。想要将包装器存储在同一个容器中。
只要函数签名始终相同(在这种情况下,它固定为bool()),此示例就可以工作。
struct func_base {
virtual ~func_base() {};
virtual bool operator()() const = 0;
};
template <typename C>
class func_wrapper : public func_base {
public:
typedef bool (C::*member_func_ptr_t)();
func_wrapper(member_func_ptr_t func_ptr, C* instance_ptr)
: m_func_ptr(func_ptr), m_instance_ptr(instance_ptr) {}
bool operator()() const { return (m_instance_ptr->*m_func_ptr)(); }
private:
member_func_ptr_t m_func_ptr;
C* m_instance_ptr;
};
您还可以创建一个辅助函数来创建自动推断成员类型的包装器。
/* This function returns a pointer to dynamically *
* allocated memory and it is thus the callers *
* responsibility to deallocate the memory!! */
template <typename C>
func_base* make_wrapper(bool (C::*func_ptr)(), C* instance_ptr) {
return new func_wrapper<C>(func_ptr, instance_ptr);
}
现在您可以使用它,例如像这样:
struct Bar { // Define some other class with member function.
bool memberFunc() { return false; }
};
int main() {
Foo foo; // Create object instances.
Bar bar; // ----------||-----------
std::deque<func_base*> d; // Deque storing pointers to base class.
// Push pointer to any member func.
d.push_back(make_wrapper(&Foo::memberFunc, &foo));
d.push_back(make_wrapper(&Bar::memberFunc, &bar));
for (std::deque<func_base*>::iterator it = d.begin(); it != d.end(); ++it) {
(**it)(); // Call all functions in deque.
}
for (std::deque<func_base*>::iterator it = d.begin(); it != d.end(); ++it) {
delete *it; // REMEMBER to destroy wrappers pointed to!!
}
}
这将使用 C++03 编译器进行编译。请参阅使用 gcc 4.3.2 编译的 live demo。
注意:如果需要,您可以轻松地修改包装类以存储实例的副本。