我很好奇如何将派生指针和基类实际运行起来。 这是一个例子:
struct A {};
struct B : A {};
// Boxing a pointer to an instance of B
void* p = new B();
现在,假设我想通过指针p访问A的可能成员或方法。
A* a1 = (A*)p;
A* a2 = (A*)((B*)p);
哪一个是正确的?总的来说有什么区别吗? 你能告诉我在哪里可以获得有关这个主题的更多信息吗?
答案 0 :(得分:1)
在这种情况下,在实践中没有区别。
但可能存在差异if there is multiple inheritance:
#include <cstdio>
struct A { int x; };
struct B { int y; };
struct C : B, A {};
int main() {
void* c = new C();
printf("%p\n", c); // 0x1000
printf("%p\n", (A*) c); // 0x1000
printf("%p\n", (A*) ((C*) c)); // 0x1004
return 0;
}
或子类有一个虚方法,但父类不是 [1] ,包括使用虚拟继承 [2] 。
就标准而言,OP使用C风格的演员,which in this case is equivalent to static_cast
。
演员序列B*
→void*
→B*
→A*
有效,前两个演员将返回§5.2.9所要求的相同指针[expr.static.cast] / 13,最后一次演员作为指针转换§4.10[conv.ptr] / 3。
但是,演员序列B*
→void*
→A*
实际上会给出未定义的结果,因为,结果未在§5.2中定义.9 / 13☺。
[1]:
#include <cstdio>
struct A { int x; };
struct C : A { virtual void g() {} };
int main() {
void* c = new C();
printf("%p\n", c); // 0x1000
printf("%p\n", (A*) c); // 0x1000
printf("%p\n", (A*) ((C*) c)); // 0x1008
return 0;
}
[2]:
#include <cstdio>
struct A { int x; };
struct C : virtual A {};
int main() {
void* c = new C();
printf("%p\n", c); // 0x1000
printf("%p\n", (A*) c); // 0x1000
printf("%p\n", (A*) ((C*) c)); // 0x1008
return 0;
}