1.1. 指向成员函数的函数指针
1.1.1. 静态成员函数指针
double (Point::*coord)() = &Point::x;
coord指向的是x的实际地址。
1.1.2. 非虚拟非静态成员函数指针
double (Point::*coord)() = &Point::x;
指针取得的是x在内存中的真正地址,但这个值不完全,他需要被绑定在某个class object的地址上,才能调用该函数。上述的指针调用:
a)(origin.*coord)();
b)(ptr->*coord)();
会被转化成为:
a)(coord)(&origin);
b)(coord)(ptr);
这样的调用成本,如果不用virtual、多重继承或virtual base class的话,并不比非成员函数指针高。
1.1.3. 虚拟成员函数指针
double (Point::*coord)() = &Point::x;
指针取得的是x在virtual Table中的索引值。
(ptr->*coord)();
会被转化为:
(*ptr->vptr[(int)coord])(ptr);
那么如何才能够知道coord使地址还是索引呢?这就必须引入一个更一般如下的规则。
1.1.4. 多重继承下的成员函数指针
0001 struct _mptr
0002 {
0003 int delta; //this指针的offset值
0004 int index; //vtbl中的索引值
0005 union
0006 {
0007 ptrtofunc faddr; //函数地址
0008 int v_offset; //virtual或多重继承的第二个或后继的Base Class的vptr
//的位置,如果vptr放在对象的开头,就没有用了,代价是兼容
//性降低
0009 };
0010 };
(ptr->*coord)();
会被转化为:
(coord.index < 0)
? //非虚函数
(*coord.faddr)(ptr)
: //虚函数
(*ptr->vptr[coord.index](ptr));
1.2. 函数效率
效率
名称
高
低
内联函数(Inline menber)
非成员函数(Nomember)
静态成员函数(static member)
非静态成员函数(Nostatic member)
虚函数(virtual member)
多重继承虚函数(virtual member)
虚拟继承虚函数(virtual member)
1.3. 函数指针效率
效率
名称
高
低
指向非成员函数的指针
指向成员函数的指针
多重继承的非虚函数指针
虚继承的非虚函数指针
指向虚成员函数的指针
多重继承的虚成员函数的指针
虚继承的虚成员函数的指针