2016-04-24 13 views
0

Я понимаю основную концепцию виртуальной функции и виртуальные таблицы, , но в следующем примере, я не понимаю, почему c.A(); печатаетвызов виртуальной функции в функции-члена класса

parent A 
child 

но без виртуального ключевого слова для Parent :: FUNC(), он печатает

parent A 
parent 

ли вы дайте мне знать причину в деталях? Было бы здорово объяснить с помощью таблицы v, памяти (кучи, стека) и т. Д.

Спасибо.

#include <iostream> 

template <class TYPE> class Parent 
{ 
public: 
    Parent() {}; 
    ~Parent() {}; 
    virtual void func() { std::cout << "parent" << std::endl; }; 

    void A() { 
     std::cout << "parent A" << std::endl; 
     func(); 
    } 

}; 

template <class TYPE> class Child : public Parent <TYPE> 
{ 
public: 
    Child() {}; 
    ~Child() {}; 

    void func() { std::cout << "child" << std::endl; }; 
}; 

void main() 
{ 
    Child<int> c; 
    c.A(); 
} 

ответ

2

Виртуальный ключевое слово указывает, что функция может быть переопределен в производном классе, сохраняя при этом свои свойства, требующие хотя ссылки. Это в основном триггер полиморфного поведения. Если функция объявлена ​​виртуальной и переопределена в производном классе, то vtable используется для выбора соответствующей версии функции, если не указано конкретное пространство имен. Например, Parent :: func(). Несмотря на одно и то же имя, без ключевого слова virtual две функции, которые вы назвали func(), совершенно разные. Ссылка на базовый класс, доступ к версии функции производного класса, отсутствует. Он использует единственную версию func(), о которой она знает, которая является той, которая определена в базовом классе.

0

@Pemdas дал хорошее объяснение. Вот моя попытка.

c.A() сообщает компилятору «Я собираюсь назвать не виртуальную функцию A, определенную в моем родительском классе». Это приводит к Parent::A(&c)

Метод A в классе Parent переводится как «получить виртуальные таблицы в объекте & с, возьмите указатель на функцию в первом ряду, и называет его». Поскольку c выполняет функцию func, указателем функции будет c реализация функции func. Это будет то, что вы видите.