成员表示的指针

问题描述 投票:11回答:2

我正在尝试从成员函数进行一些回调,并且一切正常,直到当我遇到以下错误时,我尝试使用从2个类派生的模板类作为回调对象:

error C2440: 'reinterpret_cast' : Pointers to members have different representations; cannot cast between them

这件事告诉我成员函数指针具有不同的表示形式(doh!)

这些表示是什么?它们之间有什么区别?

c++ function-pointers member-function-pointers
2个回答
18
投票
Danny Kalev explains this quite nicely

成员指针的基本表示形式

尽管指向成员的指针的行为类似于普通的指针,但它们在后台的表示形式却大不相同。实际上,在某些情况下,指向成员的指针通常由包含最多四个字段的结构组成。这是因为指向成员的指针不仅必须支持普通成员函数,而且还必须支持虚拟成员函数,具有多个基类的对象的成员函数以及虚拟基类的成员函数。因此,最简单的成员函数可以表示为两个指针的集合:一个指针保持成员函数的物理内存地址,第二个指针保持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

请注意,根据所涉及的类以及成员函数是否为虚拟,这些指针中的每个指针可能具有不同的表示形式。

3
投票
这是Microsoft的事情:在某些情况下,它们使指向成员函数的指针变小,以产生指向具有不同表示形式的成员函数的指针为代价,如您所见。有一个开关可以将其关闭(/vmg),以便指向成员的所有指针都具有相同的表示形式。
© www.soinside.com 2019 - 2024. All rights reserved.