c++中的类成员函数指针
发生的事情
最近,想用一个QMap来创建字符串和一个函数的键值对,要用某个函数的时候,只需要根据键来获取值然后再调用就好了。也就不许要那么多的if或者switch了。
但是当我定义这个QMap时,我犯了难,我一下子不知道怎么定义,因为我是要把成员函数给放到这个QMap里面.
正常的函数指针定义
void func()
{
qDebug() << "123";
}
typedef void (*funType) ();
funType fun = func;
fun();
像上面这样,就定义了一个返回值为void,且没有参数的函数指针,并且通过指针调用了函数.但是类的成员函数又是另外一种使用方法,
定义类的成员函数指针
定义的方法:
Class A
{
public:
A();
private:
void func();
void func2();
private:
typedef void (A::*funType) (); //这里定义了类A的成员函数中返回值为void,没有参数的函数指针
QMap<QString, funType> m_funMap;
}
这上面就定义了一个QMap,根据前面的QString就可以调用对应的函数.
然后我又在调用方法上犯了难,在网上搜索之后,得到如下调用方式:
/*我先是插入了对应的键值对*/
/*
m_funMap.insert("func", A::func);
m_funMap.insert("func2", A::func2);
*/
(this->*m_funMap.value("func"))();
因为c++的成员函数的地址都是一样的,也就是说,一个类的成员函数就只有一个地址,而不是跟随实例.那么怎么区分这些实例调用的函数呢,这就需要用到this指针了,
所以,需要加上一个this来调用.
std::function
我在网上搜索的时候,发现了std::function这个东东,本着学习的心态我看了一下.
关于这个,API Reference Document std::function的解释是:
类模板 std::function 是通用多态函数封装器。 std::function 的实例能存储、复制及调用任何可调用 (Callable) 目标——函数、 lambda 表达式、 bind 表达式或其他函数对象,还有指向成员函数指针和指向数据成员指针。
存储的可调用对象被称为 std::function 的目标。若 std::function 不含目标,则称它为空。调用空 std::function 的目标导致抛出 std::bad_function_call 异常。
用这种方法的存储函数指针的方式是:
Class A
{
public:
A();
private:
void func();
void func2(int a);
private:
typedef void (A::*funType) (); //这里定义了类A的成员函数中返回值为void,没有参数的函数指针
QMap<QString, funType> m_funMap;
}
std::function<void (A::*)()> function = std::bind(A::func, this);
funtion();
// 带参数的指针如下
std::function<void (A::*) (int)> function1 = std::bind(A::func, this, std::placeholders::_1);
function1();
关于bind的介绍可以看这里API Reference Document std::bind