C++指向成员的指针
一、指向成员变量的指针并非指针
C++中指向成员变量的指针其实是一个相对于类对象的偏移量。《C++必知必会》的条款15讲述了这一说法:“与常规指针不同,一个指向成员变量的指针并不指向一个内存位置。它指向的是一个类的特定成员,而不是指向一个特定对象里的特定成员。通常最清晰的做法是将指向数据成员的指针看作为一个偏移量。......。这个偏移量告诉你,一个特定成员的位置距离对象的起点有多少个字节。”
二、指向成员函数的指针并非指针
获取非静态成员函数的地址时,得到的不是一个地址,而是一个指向成员函数的指针。为了对一个指向成员函数的指针进行解引用,需要一个对象或一个指向对象的指针。因为通过指向成员函数的指针调用该函数时,需要将对象的地址用作this指针的值,以便进行函数调用(当然,也有其它的用途)。
以下内容转自: http://blog.csdn.net/maojudong/article/details/8194143
测试目录:
1.普通函数指针指向普通函数
2.普通函数指向非静态成员函数
3. 类外部的 类函数指针 指向普通函数
4. 类外部的 类函数指针 指向成员函数
5. 类内部的 函数指针 指向成员函数 (类似于第2条)
6. 类内部的 函数指针 指向普通函数
直接上代码:
- #include <iostream>
- #include <string>
- #include <vector>
- #include <map>
- using namespace std;
- class Foo
- {
- public:
- string m_str;
- Foo()
- {
- m_str = "";
- }
- static void testFunc2(int a)
- {
- cout<<"Foo:void testFunc2(int a)"<<endl;
- cout<<a<<endl;
- }
- void testFunc4(int a)
- {
- cout<<"Foo:void testFunc4(int a)"<<endl;
- cout<<a<<endl;
- }
- static void testFunc5(int a)
- {
- cout<<"Foo:void testFunc5(int a)"<<endl;
- cout<<a<<endl;
- }
- void (*pTestFunc5)(int a);
- void (*pTestFunc6)(int a);
- };
- void (*pTestFunc1)(int a);
- void (*pTestFunc2)(int a);
- void (Foo::*pTestFunc3)(int a);
- void (Foo::*pTestFunc4)(int a);
- void testFunc1(int a)
- {
- cout<<"func1 pointer test"<<endl;
- cout<<a<<endl;
- }
- void testFunc3(int a)
- {
- cout<<"func3 pointer test"<<endl;
- cout<<a<<endl;
- }
- void testFunc6(int a)
- {
- cout<<"func6 pointer test"<<endl;
- cout<<a<<endl;
- }
- int main(int argc, const char *argv[])
- {
- Foo foo;
- //foo.test("woo",100);
- pTestFunc1 = testFunc1; //经常用这个方法
- (*pTestFunc1)(1);
- pTestFunc2=&foo.testFunc2;
- (*pTestFunc2)(2);
- //pTestFunc3 = &testFunc3; //编译器报错,不可以这么使用
- pTestFunc4 = &Foo::testFunc4; //初始化的时候必须带有&Foo::
- //pTestFunc4(4);//编译器报错,不可以这么使用
- //foo.pTestFunc4(4);//编译器报错,不可以这么使用
- //foo.*pTestFunc4(4);//编译器报错,不可以这么使用
- //foo.(*pTestFunc4)(4);//编译器报错,不可以这么使用
- (foo.*pTestFunc4)(4); //正常运行
- foo.pTestFunc5=&Foo::testFunc5;
- foo.pTestFunc5(5);
- foo.pTestFunc6=&testFunc6;
- foo.pTestFunc6(6);
- return 0;
- }