问题标签 [vptr]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
2171 浏览

c++ - 为什么 vptr 存储为具有虚函数的类的内存中的第一个条目?

对于一些编译器,如果一个类有虚函数,那么它的 vptr 可以通过其对象的第一个字节的地址来访问。例如,

我知道它取决于不同的编译器行为。由于存在将 vptr 作为第一个条目存储的情况,这样做有什么好处?这有助于提高性能还是仅仅因为使用 &b 更容易访问 vbtl?

0 投票
1 回答
731 浏览

c++ - 为什么具有虚函数的类与没有虚函数的类对齐方式不同?

Richard Powell 的这个 cppcon 演讲的启发,我创建了以下代码片段来愚弄:

这将打印:

添加virtualwho()我得到了这个

现在,向void*结构添加大小很简单,但为什么在虚拟情况下而不是在非虚拟情况下会有这种填充(Richard 在他的演讲中也提到过)?

我已经在 Ubuntu 14.04 64 位上使用 gcc 5.3.0 和 clang 3.7.1 对其进行了测试

0 投票
2 回答
113 浏览

c++ - 多重继承期间的对象构造和虚拟指针

测试对象的大小为 8 个字节。所以从这个例子中可以明显看出,该对象由两个 4 字节的 _vptr 组成。由于继承的顺序是public Base1,public Base2这意味着对象应该以下列方式制作:

但从代码片段看来,该对象是这样制作的:

第一个 vptr 指向一个由 3 个函数指针组成的数组(第一个指向Base1::fun1(),第二个指向Base1::func1(),第三个指向Test::test())。

派生对象由 Base+Derived 组成。这意味着第一个字节块是 Base 对象,其余的是 Derived。如果是这样,那么在我们的 objTest 示例中,第二个应该_vptr指向三个函数指针(第一个指向Base2::fun1()和)。但是我们看到 first指向 的函数指针。Base2::func1()Test::test()_vptrTest::test()

问题:

1.这种行为编译器是特定的吗?

2.标准是否提到了这种行为?还是我的理解完全错误?

0 投票
1 回答
1222 浏览

c++ - 获取没有对象的类的vtable

我正在尝试实现一个类似于此处描述的第一个系统。也就是说,(ab)使用 vtable 修改来改变运行时的对象行为。这是我尝试在我正在处理的 C++ 项目中创建有效的类型通用包装器的一部分。

如果您无法访问该示例,请使用以下方式复制 vtablememcpy()this指针:

但是,我对这种方法有一个问题:我没有目标类的对象来复制 vtable,并且不想创建一个对象,因为某些类型的构造成本很高。

有没有一种方法可以访问 vtable,该 vtable 将被放置到给定类的对象中,而没有该类的对象?

如果它具有某种可移植性会更好,但我在很大程度上已经接受了特定于编译器的要求;因此,如果没有其他选择,只能接受 GCC/G++ 方法。让我们也假设我只关心在相当标准的操作系统和架构上构建它。

我正在使用 C++11,如果这有助于解决这个问题。

编辑:我想完全清楚,我知道这种行为有多危险。尽管我的介绍可能会建议,我对这个想法以及它在非常受控的情况下的狭窄应用更感兴趣,而不是我对它作为生产软件的好主意。

0 投票
1 回答
637 浏览

c++ - 在多重继承的情况下选择 vptr

这与之前的许多问题相似,但它提出了一些我无法找到答案的问题。

具体来说,b2 如何指向 vptr for vtable of Derived for Base2 以获取 b2_fn()?我试过从 gcc 看到 memlayout 转储,但想不通。

0 投票
1 回答
183 浏览

c++ - 虚拟继承如何解决c++中的多重继承(Diamond)?会走哪条路?

下面的代码是关于钻石问题的。虚拟继承解决了这种歧义。

  1. 虚拟继承如何解决这个问题?它会有vtable条目吗?
  2. 编译器采用哪条路径到达父类?
0 投票
2 回答
342 浏览

c++ - C++中vptr和vtable的概念

为什么只有默认构造函数只能创建 vptr(Virtual Table Pointer) 和 vtable(Virtual Table)?为什么参数构造函数不能

0 投票
4 回答
698 浏览

c++ - memcpy derived class to base class, why still called base class function

I am reading Inside the C++ Object Model. In section 1.3

So, then, why is it that, given

the instance of rotate() invoked is the ZooAnimal instance and not that of Bear? Moreover, if memberwise initialization copies the values of one object to another, why is za's vptr not addressing Bear's virtual table?

The answer to the second question is that the compiler intercedes in the initialization and assignment of one class object with another. The compiler must ensure that if an object contains one or more vptrs, those vptr values are not initialized or changed by the source object .

So I wrote the test code below:

The result

My question is why b_memcpy still called Base::vfunc()

0 投票
1 回答
252 浏览

c++ - vtable:底层算法

我对 vtables 的理解是,如果我有一个带有虚函数 speak() 以及子类 Lion 和 HouseCat 的类 Cat,那么就会有一个 vtable 将 speak() 映射到每个子类的正确实现。于是打了个电话

编译为

即在 vtable 位置 0 中查找并在该位置调用函数指针。

我的问题是:多重继承会发生什么?

让我们添加一个类 Pet。Pet 有虚函数 speak() 和 eat()。HouseCat 扩展了 Pet,而 Lion 没有。现在,我需要确保

编译为

也就是说 vtable[0] 需要是 speak()。Pet.eat 需要是 slot 1。那是因为 cat.speak() 需要访问 vtable 中的 slot 0,如果对于 HouseCat,slot 0 恰好是eat,这将出现可怕的错误。

编译器如何确保 vtable 索引组合在一起?

0 投票
1 回答
942 浏览

c++ - 派生类中vtable的理解

我试图用虚拟表和继承来理解一些低级的东西。

当您通过继承两个类并添加新的虚函数来创建新类时,vptr 将存储在哪里?

在我看来,在这种情况下,编译器会执行一些“vptr 优化”。我正试图弄清楚。

假设我们有以下结构:

在 x86 和 align=4 的情况下,AB内存中将如下所示:

但是当我尝试重新组装时C,我得到了这个:

那么vptr在C哪里呢?我可以假设编译器合并不同的虚拟表(例如 vptr of Aand C),但在那种情况下为什么sizeof(C)返回sizeof(A)++ sizeof(sizeof(B) vptr sizeof(alligned_char))

有同样的struct D : public C {}故事 - 没有 vptr 的D

我使用的编译器是 msvc 2012 x86。