【问题标题】:Modify protected value with structure用结构修改保护值
【发布时间】:2014-01-21 17:51:15
【问题描述】:

我有课:

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

它不再起作用了。

为什么它适用于 virtual 而不是没有?

我正在考虑 VTables。

提前致谢:)

【问题讨论】:

  • 你不能那样做,FruitInTheMatrixFruit 是完全不相关的类。不要使用reinterpret_cast&lt;&gt;,除非你 100% 确定你在做什么!!
  • 您这样做是在自找麻烦。如果有人在 vitamins 的定义之前向任一类添加了新的成员变量,那么您的代码将会失败。
  • 正如 microsoft 网站 (msdn.microsoft.com/en-us/library/e0w9f63b.aspx) 中所说:“reinterpret_cast 的结果除了被强制转换回其原始类型之外,不能安全地用于任何其他用途。其他用途充其量是不可移植的”

标签: c++ class struct virtual vtable


【解决方案1】:

因为类实例的大小发生了变化,随之而来的是vitamins 成员的偏移量。这是因为 virtual 函数将导致在分配给成员的内存之前将 vtable 指针存储在实例中,正如您所猜测的那样。

小心! reinterpret_cast 可以杀死你的小猫!

【讨论】:

    【解决方案2】:

    您对Fruit 的声明可能至少包含一个虚函数。

    在虚拟函数的常见实现中使用虚拟表。指向虚拟表的指针作为 first 元素存储在对象的内存表示中。不管你在哪里声明一个虚函数,虚表总是在开头。

    因此,通过在InTheMatrixFruit 中声明一个虚函数,您可以在int vitamins 之前创建一个“填充”,使其与Fruitvitamins 匹配。

    【讨论】:

      猜你喜欢
      • 2020-05-23
      • 2012-02-26
      • 1970-01-01
      • 2012-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-19
      相关资源
      最近更新 更多