Подтвердить что ты не робот

Где в памяти хранится vtable?

Где в памяти хранится vtable?

4b9b3361

Ответ 1

Зависит от компилятора.

В VС++ указатель vtable, хранящийся в начале выделения объекта, перед любыми данными элемента. (Если ваш класс имеет хотя бы одну виртуальную функцию-член.)

Также может быть несколько указателей vtable, если ваш класс умножает-наследует от других классов с помощью vtables.

Сам Vtables статически выделяется где-то в вашем адресном пространстве.

Затем макет объекта выглядит как (для экземпляра C):

A VTable ptr
A member variables.
B Vtable ptr
B member variables.
C member variables.

для гериархии

class A {
  virtual Ax() {}
  int a, b;
};
class B {
  virtual Bx() {}
  int c, d;
};
class C : public A, public B {
  int foo, bar;
};

Ответ 2

виртуальные таблицы? Что такое vtable? В стандарте С++ не упоминается vtable. Каждый компилятор может реализовать виртуальные функции по своему усмотрению. И это включает в себя размещение vtable в любом месте, которое ему нравится.

Ответ 4

Обычно vptr в начале объекта (Imperfect С++, Backyard Hotrodding С++), но это не гарантируется стандартом. Использование vptrs и vtables в стандарте не гарантируется.

Если вам действительно нужно знать, где это, обычно используют что-то вроде COM, XPCOM, UNO и т.д., которые реализуются, по существу, с заданным местом, где расположено что-то вроде vptr, и устанавливают способы использования их.

Ответ 5

Каждый экземпляр, содержащий виртуальную функцию, имеет указатель виртуальной функции, который указывает на таблицу виртуальных функций (vbtl), мы могли бы найти vtbl через экземпляр. или вы можете использовать objdump для чтения символа файла ELF, возможно, вы найдете ответ. Надеюсь, следующий пример поможет вам.

#include <iostream>
#include <stdio.h>
typedef void (*fun_pointer)(void);

using namespace std;
class Test
{
 public:
   Test()
    {
     cout<<"Test()."<<endl;
    }
   virtual void print()
    {
     cout<<"Test::Virtual void print()."<<endl;
    }
   virtual void print2()
    {
     cout<<"Test::virtual void print2()."<<endl;
    }
};

class TestDrived:public Test
{
 public:
  TestDrived()
    {
    cout<<"TestDrived()."<<endl;
    }
  virtual void print()
    {
    cout<<"TestDrived::virtual void print()."<<endl;
    }
  virtual void print2()
    {
    cout<<"TestDrived::virtual void print2()."<<endl;
    }
  void GetVtblAddress()
    {
        cout<<"vtbl address:"<<(int*)this<<endl;
    }
  void GetFirstVtblFunctionAddress()
    {
    cout<<"First vbtl function address:"<<(int*)*(int*)this+0 << endl;
    }
  void GetSecondVtblFunctionAddress()
    {
    cout<<"Second vbtl function address:"<<(int*)*(int*)this+1 << endl;
    }
  void CallFirstVtblFunction()
    {
    fun = (fun_pointer)* ( (int*) *(int*)this+0 );
    cout<<"CallFirstVbtlFunction:"<<endl;
    fun();
    }
  void CallSecondVtblFunction()
    {
    fun = (fun_pointer)* ( (int*) *(int*)this+1 );
    cout<<"CallSecondVbtlFunction:"<<endl;
    fun();
    }
private:
    fun_pointer fun;
};



int main()
{
 cout<<"sizeof(int):"<<sizeof(int)<<"sizeof(int*)"<<sizeof(int*)<<endl;
 fun_pointer fun = NULL;
 TestDrived a;
 a.GetVtblAddress();
 a.GetFirstVtblFunctionAddress();
 a.GetSecondVtblFunctionAddress();
 a.CallFirstVtblFunction();
 a.CallSecondVtblFunction();
 return 0;
}

Ответ 6

Vptr и Vtable сохраняются в сегменте данных...

Vtable похож на массив указателя на функцию.

Vtable и Vptr создают во время компиляции, которая будет получать память во время выполнения, а записи vtable - это адреса виртуальных функций.

Каждый объект класса, содержащего виртуальную функцию, будет иметь дополнительный указатель, который указывает на Виртуальную таблицу, называется виртуальным указателем.

всякий раз, когда мы вызываем виртуальную функцию с использованием объекта, сначала возбуждающий Vptr считывает функцию из Vtable во время выполнения и, наконец, функцию будет вызываться.