Нарезка объектов виртуальных функций - PullRequest
5 голосов
/ 13 августа 2010

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

    class A{

    public:
     virtual void func(){ cout<<"\n In A:func";}
    };

    class B:public A{

    public:
     virtual void func(){ cout<<"\n In B:func";}
    };

   main(){
    A *ptr1 = new B();

    A oA = *ptr1;

    oA.func(); 
  }




      DerviedClassObjectB:
         +0: pointer to virtual method table of B 

       virtual method table of B:
         +0: B::func

Над программой выводится "In A :: func".

Но как обходится без виртуальной таблицы для класса B, зная о базовом классе A :: func, в итоге вызывая A :: func

Ответы [ 2 ]

14 голосов
/ 13 августа 2010
A oA = *ptr1;

Копирует все переменные-члены в новый объект А. Указатель vtable не является обычной переменной-членом и не скопирован. Таким образом, любые последующие виртуальные функции, вызываемые для этого объекта, будут действовать так, как если бы он был объектом A, поскольку он является объектом A.

14 голосов
/ 13 августа 2010

"Виртуальный стол для класса B"? Виртуальная таблица для класса B вообще не участвует в вызове oA.func(). Объект oA имеет тип A, что означает, что его виртуальная таблица принадлежит классу A.

Более того, большинство компиляторов оптимизируют вызов oA.func(), чтобы он вообще не использовал виртуальные таблицы. Поскольку тип oA известен во время компиляции, вызов oA.func() может быть сразу направлен на A::func без использования виртуальных таблиц.

...