我知道我可以获取指向类或结构的数据成员的指针,但以下代码的最后一行无法编译:
struct abc
{
int a;
int b;
char c;
};
int main()
{
typedef struct abc abc;
char abc::*ptt1 = &abc::c;
void *another_ptr = (void*)ptt1;
}
为什么我不能将ptt1转换为another_ptr?我们正在讨论指针,因此一个指针应该具有与另一个指针类似的维度(尽管在概念上不同)
答案 0 :(得分:10)
指向非静态类成员类型的指针与对象指针类型不同;他们表现得非常不同。实际上,您甚至无法取消引用*
成员的指针。要通过指向成员的指针访问成员,请改用.*
和->*
运算符。如果你可以将它强制转换为这样的对象指针类型,那么,如果你用*
取消引用它会发生什么?
只有对象指针类型具有标准转换为void*
(§4.10):
类型为“指向 cv
T
的指针的prvalue”,其中T
是对象类型,可以转换为“指向的指针的prvalue” cvvoid
“。
它们是如此不同以至于标准甚至不顾一切地确保术语“指针”不包含指向非静态成员的指针(§3.9.2):
除了指向静态成员的指针外,引用“指针”的文本不适用于指向成员的指针。
答案 1 :(得分:2)
主要原因是因为没有要求
指向成员的指针具有相同的大小和表示形式
指向数据的指针。 在实践中,很难想象一个指针
因为,数据成员无法适应
事实上,正如Steve Jessop指出的那样,指向成员的指针确实需要额外的信息,因为如果成员位于虚拟基础中,其偏移量取决于派生的最大类,并且必须根据指针中的附加信息动态计算。 void*
指向数据成员的指针实际上只需要包含一个
偏移。粗略地说,指向数据成员的指针将会
永远不需要大于size_t
,而void*
必须是size_t
至少与void*
一样大。另一方面,它可以
容易包含指针中不合法的位模式。
更一般地说,char*
只能包含指向数据的指针。
它必须与最大的数据指针一样大(通常
一个{{1}}),但指向函数和成员指针的指针可以
更大,不适合(几乎指向成员函数的指针)
从不适合)。
答案 2 :(得分:0)
你想做这样的事吗?
struct ABC
{
int a;
int b;
char c;
};
int main()
{
ABC abc;
char *ptt1 = &abc.c;
void *another_ptr = (void*)ptt1;
}