多态性:运行时铸造指针

时间:2012-08-12 12:36:57

标签: c++ inheritance pointers casting void-pointers

我很好奇如何将派生指针和基类实际运行起来。 这是一个例子:

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);

哪一个是正确的?总的来说有什么区别吗? 你能告诉我在哪里可以获得有关这个主题的更多信息吗?

1 个答案:

答案 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;
}
相关问题