成员表示的指针 [英] Pointers to members representations

查看:94
本文介绍了成员表示的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从成员函数中做一些回调,一切正常,直到我试图使用从2类派生的模板类作为回调对象,当我得到以下错误:

 错误C2440:'reinterpret_cast':成员的指针有不同的表示;不能在它们之间转换

这个东西表示成员函数指针有不同的表示(doh!)

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

解决方案

Danny Kalev很好地解释了这一点:


表示指向成员的指针



虽然指向成员的指针像普通指针一样,但在幕后,它们的表示是完全不同的。实际上,在某些情况下,指向成员的指针通常由一个包含最多四个字段的结构组成。这是因为指向成员的指针不仅必须支持普通成员函数,而且还支持虚拟成员函数,具有多个基类的对象的成员函数和虚拟基类的成员函数。因此,最简单的成员函数可以表示为一组两个指针:一个保存成员函数的物理存储器地址,第二个指针保存 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字节




请注意,具有不同的表示,取决于所讨论的类以及成员函数是否是虚拟的。



I'm trying to make some callbacks from member functions and everything was ok until I tried to use a template class derived from 2 classes as callback object when I got the following error:

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

This thing signaled me that member function pointers have different representations(doh!)

What are these representations? What is the difference between them?

解决方案

Danny Kalev explains this quite nicely:

The Underlying Representation of Pointers to Members

Although pointers to members behave like ordinary pointers, behind the scenes their representation is quite different. In fact, a pointer to member usually consists of a struct containing up to four fields in certain cases. This is because pointers to members have to support not only ordinary member functions, but also virtual member functions, member functions of objects that have multiple base classes, and member functions of virtual base classes. Thus, the simplest member function can be represented as a set of two pointers: one holding the physical memory address of the member function, and a second pointer that holds the this pointer. However, in cases like a virtual member function, multiple inheritance and virtual inheritance, the pointer to member must store additional information. Therefore, you can't cast pointers to members to ordinary pointers nor can you safely cast between pointers to members of different types.

To get a notion of how your compiler represents pointers to members, use the sizeof operator. In the following example, the sizes of a pointer to data member and a pointer to a member function are taken. As you can see, they have different sizes, hence, different representations:

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

Note that each of these pointers may have a different representation, depending on the class in question and whether the member function is virtual.

这篇关于成员表示的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆