每个类的非静态成员函数都含有一个指向被调用对象的指针,这个指针被称为this。
在非const成员函数中它的类型是指向该类类型的指针。
在const 成员函数中是指向const 类类型的指针。
在volatile 成员函数中是指向volatile 类类型的指针。
所有类的成员函数(包括非静态和静态)都是在.text段里面,这里不存在静态与非静态的区别。
在《C++ Primer》中有那么一段,在类的非静态成员函数指针和普通函数指针之间的不匹配是由于这两种指针在表示上的区别:
普通函数指针存储函数的地址可以被用来直接调用那个函数关于函数指针
类的非静态成员函数指针首先必须被绑定在一个对象或者一个指针上才能得到被调用对象的this指针,然后才调用指针所指的成员函数。
故此,在类的静态成员函数和外部接口函数中:(假定一个类T的非静态函数指针成员变量int (T::*m_ProFunc)(int , int), 存在int T::funcA(int, int))
这些函数都没有this指针,同时因为类的非静态函数成员含有this指针的原因,无法在这些函数内操作类的非静态函数指针来调用指向的类静态函数。
在这些函数内,当你尝试使用实例对象进行操作时,例如给一个实例的形参T* t; 然后在函数里面通过指针操作该类(t->*m_ProFunc)(a, b),就无法通过编译,因为编译器做了函数识别与校验。
是的,(t->T::*m_ProFunc)(a, b)这种调用函数的方式在静态成员函数或外部接口函数都无法使用。
这里理解为在程序加载到内存后,this需要有对应的内存地址才能有效使用,否则一个指针指向未知的地址就会引发coredump;因为C++实现可能不对this做空判断,所以这个直接在编译器上在编译时对代码进行了校验。既然类的非静态函数都包括了这样一个指针参数this,那么在类的静态成员函数或者外部接口函数中,可以对类的非静态成员函数指针变量进行赋值操作,但不能直接使用该变量来调用所指的成员函数。
对于必须绑定在一个对象或者一个指针上的理解,意味着想在外部函数或者静态函数中使用函数指针调用所指成员函数,仅仅只有一个类的形参是不够的,还需要在该函数加入一个类的非静态成员函数指针形参,用来绑定函数指针。也就是在外部函数或者静态成员函数中,类的形参T t,不能直接使用t.m_ProFunc(a, b),只能绑定形参Func, t.Func(a, b)。不管这个形参的实参是&T::funcA(a, b),还是t.m_ProFunc(a, b)。