繁体   English   中英

将指向数据成员的指针转换为 void *

[英]Convert pointer to data member to void *

我知道我可以获得一个指向类或结构的数据成员的指针,但以下代码的最后一行无法编译:

struct abc
{
    int a;
    int b;
    char c;
};

int main()
{
    char abc::*ptt1 = &abc::c;
    void *another_ptr = (void*)ptt1;
}

为什么我不能将 ptt1 转换为 another_ptr? 我们谈论的是指针,所以一个指针应该与另一个指针具有相似的维度(尽管概念上不同)?

指向非静态类成员类型的指针对象指针类型不同 他们的行为非常不同。 实际上,您甚至不能使用*取消引用指向成员的指针。 要通过指向成员的指针访问成员,请改用.*->*运算符。 如果您可以将它转换为这样的对象指针类型,那么如果您使用*取消引用它会发生什么?

只有对象指针类型具有到void*的标准转换(第 4.10 节):

类型为“指向cv T指针”的纯右值(其中T是对象类型)可以转换为类型为“指向cv void指针”的纯右值。

它们是如此不同,以至于标准甚至不遗余力地确保术语“指针”不包括指向非静态成员的指针(第 3.9.2 节):

除了指向静态成员的指针,引用“指针”的文本不适用于指向成员的指针。

主要原因是因为不要求指向成员的指针与指向数据的指针具有相同的大小和表示形式。 实际上,很难想象指向数据成员的指针不能放入 void* ,因为指向数据成员的指针实际上只需要包含一个偏移量。 粗略地说,指向数据成员的指针永远不需要大于 size_t ,并且 void*必须至少与 size_t一样大。 另一方面,它很容易包含在指针中不合法的位模式。 事实上,正如 Steve Jessop 指出的那样,指向成员的指针确实需要额外的信息,因为如果成员在虚拟基类中,它的偏移量取决于派生最多的类,并且必须根据指针中的额外信息动态计算。

更一般地说, void*只能包含一个指向数据的指针。 它必须与最大的数据指针(通常是char* )一样大,但指向函数和成员指针的指针可以更大,并且不适合(并且指向成员函数的指针几乎永远不会适合)。

你想做这样的事情吗?

struct ABC
{
    int a;
    int b;
    char c;
};

int main()
{
    ABC abc;
    char *ptt1 = &abc.c;
    void *another_ptr = (void*)ptt1;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM