【问题标题】:C++ vptr is duplicated in every objectC++ vptr 在每个对象中都重复
【发布时间】:2013-05-23 10:58:06
【问题描述】:

在 c++ 中,我们在每个对象中都有 VPTR,但每个类只有一个 VTABLE。为什么 VPTR 在每个对象中?不是重复吗?

【问题讨论】:

  • 每种类型只能有一组固定的最终overidder,每个对象可以是不同的类型。

标签: c++ function virtual


【解决方案1】:

如果你有:

class base
{
   virtual void func() = 0; 
}

class a: public base
{
 public:
   virtual void func() { cout << "a" << endl; }
}

class b: public  base
{
 public:
   virtual void func() { cout << "b" << endl; }
}


void call_func(base *x)
{
    x->func();
}

int main()
{
    vector<base *> v;

    v.push_back(new b);
    v.push_back(new a);

    for(int i = 0; i < v.size(); i++)
        call_func(v[i]);
}

“call_func”如何知道要调用func 中的哪一个?

原来它使用 vtable (vptr) 来找到要调用的func

[是的,代码是一个巨大的内存泄漏 - 我试图保持简单]

【讨论】:

    【解决方案2】:

    没有运行时类型信息,您不知道对象在哪个类中。因此,为了调用方法,您需要存储类信息,然后使用它来查找要调用的正确 vtable。将指针放入每个对象更容易(也更直接)。

    【讨论】:

    • 请注意,vptr也是对象类型信息的访问者。
    • 只有在某个方法存在于对象的类中时,它才能被访问——所以它是间接的。除非您进行一些特定于实现(和讨厌)的黑客行为,否则无法显式获取 vptr 并使用它来估计对象类,因为规范没有详细说明 vtable 的布局/使用。
    • 它是用户不可见的,但它被实现清楚地使用,例如在typeiddynamic_cast
    【解决方案3】:

    首先,标准无法保证这一切,您需要讨论特定的编译器才能获得特定的答案。

    动态绑定在对象级别起作用。一个类永远不会被多态地使用,一个对象是。所以你需要弄清楚某个函数是如何在每个对象的基础上绑定的。

    【讨论】:

      【解决方案4】:

      内存中的 C++ 对象实例如何引用它的 VTABLE? 但是,VPTR-VTABLE 是编译器特定的实现,C++ 标准对此没有任何说明。通常,它是多态类实例的第一个(隐藏)成员。

      这是有代价的,因为有这样的隐藏成员会使 C++ 内存模型与 C 不兼容。这是一种开销,同意,但没有其他(更好的)方法可以从 C++ 对象的实例中引用 VTABLE记忆。

      【讨论】:

        【解决方案5】:

        该指针是识别对象类型的唯一方法。每个对象都必须有一个。

        【讨论】:

          猜你喜欢
          • 2012-06-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多