2013-10-07 2 views
4

В C++, в процессе динамического связывания, рассмотрим следующий пример ...Механизм Vptr и виртуальные таблицы в C++

class Base 
{ 
    virtual void fun() 
    { 
    cout<<"Base"; 
    }  
}; 

class Derived : Base 
{ 
    void fun() 
    { 
    cout<<"Derived"; 
    } 
}; 

int main() 
{ 
    Base *bptr; 
    Derived d; 
    bptr=&d; 
    bptr->fun(); 
} 

Выход выше функции «Производная» в связи с объявлением виртуального ключевого слова/динамический связывание.

Как я понял, будет создана виртуальная таблица (Vtable), которая содержит адрес виртуальных функций. В этом случае виртуальная таблица, созданная для производного класса, указывает на наследуемый виртуальный fun(). И bptr->fun() будет разрешаться до bptr->vptr->fun();. Это указывает на функцию унаследованного базового класса. Я не совсем понимаю, как называется производная функция класса?

+2

Обратите внимание, что это 'int main', а не' void main', а объявления классов должны заканчиваться символом ';'. –

+0

Ответы ниже выглядят хорошо, но если вы чувствуете необходимость читать больше по этому вопросу, я бы рекомендовал [* Внутри объектной модели C++ *] (http://www.amazon.com/Inside-Object-Model-Stanley -Lippman/dp/0201834545 /) (ISBN: 978-0201834543). –

ответ

5

Просто пошел по этой ссылке virtual table and _vptr

Это говорит о том, что рабочий процесс будет как ..

  1. base_ptr-> base_vptr ----> проверить доступ виртуальной функции в базовом классе ,

  2. base_ptr-> производная_vptr-> virtual_function() ---> для вызова/вызова виртуальной функции.

Следовательно, вызывается виртуальная функция производного класса .. Надеемся, что вы сочтете это полезным.

+0

Ссылка на эту ссылку уже ... Не предоставляет полный soln. Ваша точка 2 говорит, что виртуальная функция будет вызвана, вот в чем проблема. Но в этом случае производный должен быть вызван. –

+0

@BlueDiamond: base_ptr-> deriv_vptr-> virtual_function() ---> для вызова/вызова виртуальной функции в производном классе. Указатель базового класса будет содержать производный виртуальный указатель (производный класс виртуального указателя указывает на виртуальную таблицу производного класса) , Затем производный виртуальный указатель при вызове виртуальной функции вызывается виртуальная функция производного класса. –

+0

Выведенная виртуальная функция не должна вызываться. Виртуальная функция производного класса наследуется от базового класса .. Предполагается, что переопределенная функция будет вызвана ... –

0

И bptr-> fun() будет разрешен для bptr-> vptr-> fun() ;. Это указывает на функцию базового класса.

Неправильно. Окно vptr экземпляра Derived (скрытое поле в каждом экземпляре) указывает на таблицу Derived.

+0

Исправлена ​​функция унаследованного базового класса ... –

+0

Итак, вы понимаете, что каждый класс имеет свой собственный vtable (который говорит, какая реализация должна использоваться для каждого виртуального метода), а vptr каждого экземпляра указывает на правильную таблицу vtable, соответствующую фактическому объекту (динамический) тип. Чего не хватает? – Kos

+0

Возможно, недостающее звено в том, что 'fun' Derived также (неявно) является виртуальным? Это подразумевается, потому что обе подписи типа «fun» одинаковы. – Kos

-1

В стандарте не указывается механизм реализации полиморфизма. Все Стандарты говорят, как это должно работать, а не как производители компиляторов должны его реализовать.

Это, как говорится, у вас есть почти все, что касается GCC под Linux и MSVC под Windows, и я ожидал бы, что большинство других компиляторов будут похожи.

+0

Исправлена ​​функция унаследованного базового класса. –

+0

Делает смысл. .Vtable содержит только адрес виртуальных функций. Но как будет вызываться производная функция? В таблице vtable не содержится адрес не виртуальных функций rit .. Я хотел бы получить это разъяснение ... –

 Смежные вопросы

  • Нет связанных вопросов^_^