现在的位置: 首页 > 综合 > 正文

[C++基础]044_C++的成员函数本质[C++基础]028_获取类成员函数的指针

2012年09月10日 ⁄ 综合 ⁄ 共 1054字 ⁄ 字号 评论关闭

首先感谢bolow大神在我的博客[C++基础]028_获取类成员函数的指针里提的问题,跟bolow一起探讨得到了下面的答案。

首先看下面的程序:

 1 #include <iostream>
 2 using namespace std;
 3 class A
 4 {
 5 public:
 6     int i;
 7     A():i(0){};
 8     int foo(){return i;}
 9 };
10 
11 class B
12 {
13 public:
14     int j,k;
15     B():j(1),k(2){}
16     int foo(){return k;}
17 };
18 
19 typedef int (B::*BFPTR)();
20 int main()
21 {
22     int (A::*fptr)()= &A::foo;
23     BFPTR bfptr1=(BFPTR) fptr;
24     B b;
25     A a;
26     cout<<(b.*bfptr1)()<<endl;
27 }
22     int (A::*fptr)()= &A::foo;    将A函数的foo地址给以A为类的一个函数指针
23     BFPTR bfptr1=(BFPTR) fptr;    告诉编译器把上面的函数指针当作B的函数指针来看(A的函数指针转为B的函数指针)
24     B b;
25     A a;
26     cout<<(b.*bfptr1)()<<endl;    执行B的函数指针,其实这时候调用的是A的foo函数

输出结果:
1

这里引出一个事实:所谓的类根本就没有成员函数一说,从内存布局上也能看出来,内存布局中只有成员变量的空间,并没有成员函数的内存空间。

这是为什么呢? 那就需要知道成员函数到底是怎么被调用的。

我们看成员函数的调用:对象.成员函数() 或 对象指针->成员函数()

那成员函数实际上是如何被编译器声明的呢? 成员函数(类, 参数) 比如我们有以下的类:

1 class A{
2 public:
3      void foo(int a, int b){
4 
5       }
6 private:
7      int value;
8 };

其实上面的类其实是像下面声明的:

1 class A{
2 private:
3      int value;
4 };
5 
6 void foo(void *ptr,  int a, int b){
7 
8 }

当我们调用a.foo(1, 2)时,其实是下面的形式:

1 void foo(void *ptr,  int a, int b){...

可见,所谓的.运算符实际是把this指针传递给函数foo了。

 

那我们最开始的第一个程序里为什么会输出1呢?因为成员函数返回一个成员变量时,只是返回对象的首地址的偏移值。所以,返回了第一个参数1。

如果A类有三个参数,函数foo返回第三个参数时,那输出结果就不是所能预料的了。




抱歉!评论已关闭.