我试图从成员函数做一些回调和一切正常,直到我试图用2类为回调对象派生的模板类时,我得到了以下错误:
error C2440: 'reinterpret_cast' : Pointers to members have different representations; cannot cast between them
这件事标志着我说的成员函数指针有不同的表示(DOH!)
这些是什么表示? 它们之间有什么区别?
我试图从成员函数做一些回调和一切正常,直到我试图用2类为回调对象派生的模板类时,我得到了以下错误:
error C2440: 'reinterpret_cast' : Pointers to members have different representations; cannot cast between them
这件事标志着我说的成员函数指针有不同的表示(DOH!)
这些是什么表示? 它们之间有什么区别?
丹尼卡莱弗解释了这个相当不错 :
指针的底层表示到会员
虽然成员指针行为像普通指针,在幕后他们的表现是完全不同的。 事实上,一个指针构件通常包括最多含在某些情况下四个字段struct的。 这是因为成员指针必须支持不仅普通成员函数,而且虚拟成员函数中,具有多个基类的对象的成员函数,和虚拟基类的成员函数。 因此,最简单的成员函数可以被表示为一组两个指针:一个保持所述成员函数的物理存储器地址,和保持第二指针
this
指针。 然而,在像一个虚拟成员函数,多重继承和虚拟继承的情况下,指针构件必须存储额外的信息。 因此,你不能施放成员指针普通指针也无法将安全地转换到不同类型的成员指针之间。要了解您的编译器如何代表成员指针一个概念,使用
sizeof
操作符。 在以下示例中,一个指针到数据成员和一个指向一个成员函数的大小会被执行。 正如你所看到的,他们有不同的尺寸,因此,不同的表示:
struct A
{
int x;
void f();
};
int A::*pmi = &A::x;
void (A::*pmf)() = &A::f;
int n = sizeof (pmi); // 8 byte with my compiler
int m = sizeof (pmf); // 12 bytes with my compiler
请注意,每个这些指针可以具有不同的表示,这取决于所讨论和是否该成员函数是虚拟的类。
这是微软的事情:他们使指针成员函数在某些情况下更小,在生产指针即有不同的表示,就像刚才看到的成员函数的成本。 有一个开关的地方关闭这个功能,使所有成员指针具有相同的表示。