我上课了:
class Fruit
{
protected:
int Vitamins
[...]
public:
[...]
}
结构:
struct InTheMatrixFruit
{
int vitamins;
virtual ~InTheMatrixFruit();
};
以及在Fruit上引用的函数:
void function(Fruit &fruit);
如果我写的话,在这个函数中:
reinterpret_cast<InTheMatrixFruit&>(fruit).vitamins = 300;
它确实修改了维生素保护值。
但是,如果我像这样删除虚拟:
struct InTheMatrixFruit
{
int vitamins;
~InTheMatrixFruit();
};
它不再起作用了。
为什么它适用于虚拟而非没有?
我正在考虑VTables。
提前致谢:)
答案 0 :(得分:4)
因为类实例的大小发生了变化,并且随之改变了vitamins
成员的偏移量。这是因为你猜到,virtual
函数会导致vtable指针在分配给成员的内存之前存储在实例中。
小心! reinterpret_cast
会杀死你的小猫!
答案 1 :(得分:2)
您对Fruit
的声明可能至少包含一个虚函数。
在虚拟功能的常见实现中,使用虚拟表。指向虚拟表的指针存储为对象的内存表示中的 first 元素。在声明虚函数的位置无关紧要,虚拟表始终位于开头。
因此,通过在InTheMatrixFruit
中声明虚拟函数,您可以在 int vitamins
之前创建“填充”,以便它与vitamins
Fruit
匹配}。