【发布时间】:2013-05-23 10:58:06
【问题描述】:
在 c++ 中,我们在每个对象中都有 VPTR,但每个类只有一个 VTABLE。为什么 VPTR 在每个对象中?不是重复吗?
【问题讨论】:
-
每种类型只能有一组固定的最终overidder,每个对象可以是不同的类型。
在 c++ 中,我们在每个对象中都有 VPTR,但每个类只有一个 VTABLE。为什么 VPTR 在每个对象中?不是重复吗?
【问题讨论】:
如果你有:
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。
[是的,代码是一个巨大的内存泄漏 - 我试图保持简单]
【讨论】:
没有运行时类型信息,您不知道对象在哪个类中。因此,为了调用方法,您需要存储类信息,然后使用它来查找要调用的正确 vtable。将指针放入每个对象更容易(也更直接)。
【讨论】:
typeid或dynamic_cast中
首先,标准无法保证这一切,您需要讨论特定的编译器才能获得特定的答案。
动态绑定在对象级别起作用。一个类永远不会被多态地使用,一个对象是。所以你需要弄清楚某个函数是如何在每个对象的基础上绑定的。
【讨论】:
内存中的 C++ 对象实例如何引用它的 VTABLE? 但是,VPTR-VTABLE 是编译器特定的实现,C++ 标准对此没有任何说明。通常,它是多态类实例的第一个(隐藏)成员。
这是有代价的,因为有这样的隐藏成员会使 C++ 内存模型与 C 不兼容。这是一种开销,同意,但没有其他(更好的)方法可以从 C++ 对象的实例中引用 VTABLE记忆。
【讨论】:
该指针是识别对象类型的唯一方法。每个对象都必须有一个。
【讨论】: