为什么虚析构函数会在内存管理中产生这些差异?
我有一个班级:
class A
{
public:
A() : m_x(0) { }
~A() {}
public:
static ptrdiff_t member_offset(const A &a)
{
const char *p = reinterpret_cast<const char*>(&a);
const char *q = reinterpret_cast<const char*>(&a.m_x);
std::cout << "\n&a =" << &a << "\n&a.mx=" << &a.m_x << "\np=" << (int)p << " q=" << (int)q << '\n';
return q - p;
}
private:
int m_x;
};
如果我打电话给A a; member_offset(a);
,我会打印出来:
&a =002EFD28
&a.mx=002EFD28
p=3079464 q=3079464
如果我制作析构函数virtual
,我会得到其他地址:
&a =002EFD28
&a.mx=002EFD2C
p=3079464 q=3079468
为什么呢?虚拟析构函数对内存管理有什么影响?
答案 0 :(得分:6)
虚拟方法表指针被添加到类的每个实例 - 通常在对象的开头。它不必是析构函数,任何第一个virtual
方法都将确定虚拟方法表的生成。
答案 1 :(得分:3)
没有虚函数(并且满足各种其他约束),该类具有标准布局,并且其第一个数据成员保证与对象本身具有相同的地址。
使用一个或多个虚函数,它是多态并且不再具有标准布局,并且没有这样的保证。通常,通过向类添加隐藏指针(有时称为虚拟指针或 vptr )来实现多态,指向特定于类的虚函数表(有时已知)作为 vtable )和其他动态类型信息。在这种情况下,看起来这个指针位于声明的成员之前,导致您观察到的地址不同。