vpointer在对象中的位置 C类 { 公众: C():m_x(0){} 虚拟~C(){} 公众: 静态ptrdiff成员偏移量(常数C&C) { const char*p=重新解释强制转换(&c); const char*q=重新解释铸件(&c.m\U x); 返回q-p; } 私人: int m_x; }; 内部主(空) { C C; STD::CUT< P> C++中没有“VPONTER”。多态性和动态调度的实现留给编译器,而结果类布局没有任何指定。当然,当只给出基本子对象视图时,多态类型的对象必须携带一些额外的状态来标识具体类型。

vpointer在对象中的位置 C类 { 公众: C():m_x(0){} 虚拟~C(){} 公众: 静态ptrdiff成员偏移量(常数C&C) { const char*p=重新解释强制转换(&c); const char*q=重新解释铸件(&c.m\U x); 返回q-p; } 私人: int m_x; }; 内部主(空) { C C; STD::CUT< P> C++中没有“VPONTER”。多态性和动态调度的实现留给编译器,而结果类布局没有任何指定。当然,当只给出基本子对象视图时,多态类型的对象必须携带一些额外的状态来标识具体类型。,c++,pointers,memory-address,vtable,C++,Pointers,Memory Address,Vtable,使用vtables和vptr的实现是常见且流行的,将vptr放在类的开头意味着您不需要对单个继承的上下转换进行任何指针调整 许多C++编译器遵循(部分),它指定了类布局决策,这也可以提供一些见解。 < P>没有“VPONTER”。在C++中,多态性和动态调度的实现留给编译器,而结果类布局没有任何指定。当然,当只给出基本子对象视图时,多态类型的对象必须携带一些额外的状态来标识具体类型。 使用vtables和vptr的实现是常见且流行的,将vptr放在类的开头意味着您不需要对单个继承的上下转换进行任

使用vtables和vptr的实现是常见且流行的,将vptr放在类的开头意味着您不需要对单个继承的上下转换进行任何指针调整

许多C++编译器遵循(部分),它指定了类布局决策,这也可以提供一些见解。

< P>没有“VPONTER”。在C++中,多态性和动态调度的实现留给编译器,而结果类布局没有任何指定。当然,当只给出基本子对象视图时,多态类型的对象必须携带一些额外的状态来标识具体类型。 使用vtables和vptr的实现是常见且流行的,将vptr放在类的开头意味着您不需要对单个继承的上下转换进行任何指针调整


<>许多C++编译器遵循(部分),它指定了类似这样的类布局决策。这也可能提供一些见解。

是的,它依赖于实现,否,在不知道目标平台/编译器的情况下无法预测程序的输出。

是的,它依赖于实现,否,在不知道目标平台的情况下无法预测程序的输出事实上,它几乎总是以这样的方式来安排。然而,C++标准允许使用任何工作。我可以设想一些不需要上述的解决方案的解决方案——尽管它们可能不会作为一个真正的解决方案工作。

但是注意,如果你有多重继承,你可以有一个以上的VPTR/VTABLE。

实际上,它几乎总是这样排列的。然而,C++标准允许使用任何工作。我可以想象一些不需要上述的是真实的解决方案,尽管它们可能不会很好地工作。作为一个真正的解决方案

但是请注意,如果您有多个继承,那么一个对象可以有多个vptr/vtable

class C
{
public:
    C() : m_x(0) { }
    virtual ~C() { }

public:
    static ptrdiff_t member_offset(const C &c)
    {
        const char *p = reinterpret_cast<const char*>(&c);
        const char *q = reinterpret_cast<const char*>(&c.m_x);

        return q - p;
    }

private:
    int m_x;
};

int main(void)
{
    C c;
    std::cout << ((C::member_offset(c) == 0) ? 0 : 1);
    std::cout << std::endl;

    std::system("pause");
    return 0;
}