标签: vtable

空的虚拟表可以存在吗?

#include <iostream>
using namespace std;

class Z
{
public:
    int a;
    virtual void x () {}
};

class Y : public Z
{
public:
    int a;
};

int main() 
{
    cout << "\nZ: "  << sizeof (Z);
    cout << "\nY: "  << sizeof (Y);
} 
Run Code Online (Sandbox Code Playgroud)

因为Y继承了Z,所以也会有虚表。美好的。但是,它没有任何虚函数,那么 Y 的虚表的内容是什么?
会空吗?

c++ virtual vtable

3
推荐指数
1
解决办法
628
查看次数

基类中的虚拟继承和空虚表

有这个代码:

#include <iostream>

class Base
{
   int x;
};

class Derived : virtual public Base
{
   int y;
};

int main()
{
    std::cout << sizeof(Derived) << std::endl; // prints 12
    return 0;   
}
Run Code Online (Sandbox Code Playgroud)

我已经读过,当某个类被虚拟继承时,会为类派生创建空虚表,因此内存布局如下:

Derived::ptr to empty vtable
Derived::y
Base::x
Run Code Online (Sandbox Code Playgroud)

它是 12 个字节。问题是 -如果没有任何虚拟方法,这个空的vtable 的目的是什么,它是如何使用的?

c++ virtual-inheritance vtable memory-layout vptr

3
推荐指数
1
解决办法
3210
查看次数

如何使用 gdb 按名称显示 vtable

在有故障转储的地方调试时,vtable 指针是内存中对象的良好指示器。

我想在 gdb 中做的是能够通过执行类似的操作来查询 vtable

info address 'vtable for Bar'
Run Code Online (Sandbox Code Playgroud)

但是,我找到的唯一方法(不需要对象的有效实例)是对 vtable 使用损坏的名称。

例子:

info address _ZTV3Bar
Run Code Online (Sandbox Code Playgroud)

尝试找出 vtable 损坏的名称并不是世界末日,但它很烦人(即使用 objdump -t myexecutable)。

有没有人知道我可以以一种不那么痛苦的方式找到类型的 vtable 地址的方法(不需要类型的有效实例)?
- 规则:不能要求有问题的对象的有效实例并在对象中找到 vtable 指针。

c++ debugging gdb vtable

3
推荐指数
2
解决办法
6659
查看次数

虚函数效率和“final”关键字

考虑一个程序,它有一个类,其中包含如下声明的Foo函数:Foo::fn

virtual void fn();
Run Code Online (Sandbox Code Playgroud)

和一个Foo名为 的子类Bar。将Bar::fn这样声明:

virtual void fn() override final;
Run Code Online (Sandbox Code Playgroud)

导致对fninBar或 的子类的调用Bar更加有效,还是只会阻止 的子类Bar被覆盖fn?如果使用 使调用更加高效final,那么最简单、最有效的定义方法是什么,Bar::fn使其功能与 完全相同Foo::fn

c++ performance vtable c++11

3
推荐指数
1
解决办法
1805
查看次数

为什么需要虚拟重击?

这个问题是关于虚函数调用的(可能的)实现(我相信它被使用gcc)。

考虑以下场景:

  1. 类 F 继承自类 D(也可能是其他类),而类 D 又继承自类 B(不是虚拟的)。f()D 重写B 中声明的虚方法;实例化 F 类型的对象
  2. 类 F 继承自类 D(也许还有其他类),类 D 又继承自类 B(实际上)。f()D 重写B 中声明的虚方法;实例化 F 类型的对象

(这两种场景唯一的区别是B类的继承方式)

在场景 1 中,在对象 B 的 vtable 中,在目标位置处f()现在有一个(非虚拟)thunk 表示:

如果你想调用f(),首先thisoffset

(实际上是D把这个thunk放在那里)

在场景 2 中,在对象 B 的 vtable 中,在指定的位置f()现在有一个(虚拟)thunk 表示:

如果要调用f(),请首先将this指针更改为存储在的值addr

this(D无法准确告诉B指针需要调整多少,因为它不知道B对象在F对象最终内存布局中的位置)

g++ -fdump-class-hierarchy这些假设是通过结合查看的输出来做出的g++ -S。它们正确吗? …

c++ g++ vtable thunk

3
推荐指数
1
解决办法
950
查看次数

cpp - vtable 指针在构造/销毁期间是否被更改

因此,当在ctor/dtor基类中使用派生类并调用成员函数(包括虚拟)时,无论this是否通过指针,都会调用相关类的函数。

怎么会?vtable在此过程中对象的指针是否以某种方式被更改?因为,据我所知,vtable除非使用多重继承,否则对象中通常只有一个指针。


我有以下代码来举例说明我的意思:

#include <stdio.h>


class B {
    public:
    B()
        { printf("B constructor!\n"); f(); g(); }
    virtual ~B()
        { printf("B destructor!\n");  f(); g(); }
    virtual void f() 
        { printf("f() in B!\n"); }
    void g() 
        { printf("g() in B!\n"); }
    void h() 
        { printf("h() in B!\n"); }
};

class D : public B {
    public:
    D()
        { printf("D constructor!\n"); f(); g(); }
    virtual ~D()
        { printf("D destructor!\n");  f(); g(); }
    virtual void f() …
Run Code Online (Sandbox Code Playgroud)

c++ vtable

3
推荐指数
1
解决办法
265
查看次数

如果有虚拟方法,是否会创建vtable?

如果我创建一个非常简单的类,如下所示:

class A
{
  public :
    virtual void foo()
    {
    }
};
Run Code Online (Sandbox Code Playgroud)

(没有虚拟析构函数)是编译器要创建vtable吗?或者现代编译器是否足够聪明以识别这种情况(可能是一个糟糕的复制和粘贴)而不是为这些类添加虚拟表?

c++ vtable

2
推荐指数
1
解决办法
247
查看次数

未定义的符号:vtable

所以这是这些编译器错误之一,我无法弄清楚问题的根源.

这是类LocalQualityMeasure,标题

#include <unordered_set>

#include "../clustering/Clustering.h"
#include "../graph/Graph.h"

namespace Project {

/**
 * Abstract base class for all local clustering quality measures.
 */
class LocalQualityMeasure {


public:

    LocalQualityMeasure();

    virtual ~LocalQualityMeasure();

    virtual double getQuality(std::unordered_set<node>& C, Graph& G) = 0;
};

} /* namespace Project */
Run Code Online (Sandbox Code Playgroud)

和来源:

#include "LocalQualityMeasure.h"

namespace Project {

LocalQualityMeasure::LocalQualityMeasure() {
}

LocalQualityMeasure::~LocalQualityMeasure() {
    // TODO Auto-generated destructor stub
}


} /* namespace Project */
Run Code Online (Sandbox Code Playgroud)

这是一个派生类Conductance,标题

#include <algorithm>

#include "LocalQualityMeasure.h"

namespace Project {

class Conductance: …
Run Code Online (Sandbox Code Playgroud)

c++ gcc vtable c++11

2
推荐指数
1
解决办法
4336
查看次数

多重继承,虚函数和C++中的虚拟表

我知道vtable查找虚函数要比直接函数调用慢很多,因为基类必须搜索vtable来获取派生函数.如果有更多的派生层,如果它会更慢,我就会徘徊.基本上,我的问题如下:

基础 - > 衍生的(1层继承)虚拟函数调用的速度比 - > Derived1 - > Derived2的 - > Derived3 - > DerivedEtc(多层)虚拟函数调用?

c++ inheritance vtable

2
推荐指数
1
解决办法
646
查看次数

ZTV,ZTS,ZTI在gdb x/nfu"vtable_address"的结果中意味着什么?

代码

class Parent {
 public:
  virtual void Foo() {}
  virtual void FooNotOverridden() {}
};

class Derived : public Parent {
 public:
  void Foo() override {}
};

int main() {
  Parent p1, p2;
  Derived d1, d2;
}
Run Code Online (Sandbox Code Playgroud)

2. gdb命令

(gdb) x/300xb 0x400b30
Run Code Online (Sandbox Code Playgroud)

0x400b30 是d vtable的第一个地址.

3. gdb结果

0x400b30 <_ZTV7Derived>:    0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x400b38 <_ZTV7Derived+8>:  0x80    0x0b    0x40    0x00    0x00    0x00    0x00    0x00
0x400b40 <_ZTV7Derived+16>: 0x60    0x0a    0x40    0x00    0x00    0x00    0x00    0x00
0x400b48 <_ZTV7Derived+24>: 0x70    0x0a …
Run Code Online (Sandbox Code Playgroud)

c++ assembly gdb name-mangling vtable

2
推荐指数
1
解决办法
236
查看次数