类成员函数指针指向类中的非静态成员函数时,有如下两种情况:
* 对于nonstatic member function (非静态成员函数)取地址,获得该函数在内存中的实际地址
* 对于virtual function(虚函数),其地址在编译时期是未知的,所以对于virtual member function
(虚成员函数)取其地址,所能获得的只是一个索引值。
举例:
//指向类成员函数的函数指针
#include <iostream>
#include <cstdio>
using namespace std;
class A
{
public:
A(int aa = 0) : a(aa){}
void setA(int aa = 1)
{
a = aa;
}
virtual void print()
{
cout << "A: " << a << endl;
}
virtual void printa()
{
cout << "A1: " << a << endl;
}
private:
int a;
};
class B : public A
{
public:
B() : A(), b(0){}
B(int aa, int bb) : A(aa), b(bb){}
virtual void print()
{
A::print();
cout << "B: " << b << endl;
}
virtual void printa()
{
A::printa();
cout << "B: " << b << endl;
}
private:
int b;
};
int main(void)
{
A a;
B b;
void (A::*ptr)(int) = &A::setA;
A* pa = &a;
//对于非虚函数,返回其在内存的真实地址
printf("A::set(): %p\n", &A::setA);
//对于虚函数,返回其在虚函数表的偏移位置
printf("B::print(): %p\n", &A::print);
printf("B::print(): %p\n", &A::printa);
a.print();
a.setA(10);
a.print();
a.setA(100);
a.print();
//对于指向类成员函数的函数指针,引用时必须传入一个类对象的this指针,所以必须由类实体调用
(pa->*ptr)(1000);
a.print();
(a.*ptr)(10000);
a.print();
return 0;
}
输出:
A::set(): 0x8048a38
B::print(): 0x1
B::print(): 0x5
A: 0
A: 10
A: 100
A: 1000
A: 10000
由此引出一个问题,对于c++ 11中的std::bind(),如果绑定的是一个类非静态成员函数,则一定是 &class::mem_func,而不能是class::mem_func,因为编译器不会将对象的成员函数隐式转换成函数指针,所以必须在前面添加&; 而普通函数做实参时,会隐式转换成函数指针。区别就在于此。