Объяснение вывода кода C++, включающего виртуальную функцию

Я хочу понять причину вывода следующих программ на C++, включающих виртуальные функции. Также объясните, как таблица указателей функций и таблица виртуальных указателей, содержащая ссылки на таблицы указателей функций, будут генерироваться в следующих двух случаях и как вызов разрешается во время выполнения.

/******* PROGRAM 1 *******/
#include <iostream>
using namespace std;

class Car {
    public:
    virtual void foo() {
        cout<<"Car"<<endl;
    }
};

class Bmw: public Car {
    public:
    void foo1() {
        cout<<"Bmw"<<endl;
    }
};

int main() {
        Car *c = new Bmw(); 

        c->foo();           // gives output Car even though foo() 
                            //function does not exist in BMS class. 

        return 0;
}

/******* PROGRAM 2 *******/
#include<iostream>
using namespace std;

class Car {
    public:
    virtual void foo() {
        cout<<"Car"<<endl;
    }
};

class Bmw: public Car {
    public:
    void foo() {
        cout<<"Bmw"<<endl;
    }
};

class Bmw7: public Bmw {
    public:
    void foo1(){
        cout<<"Bmw7"<<endl;
    }
};

int main() {
    Car *c = new Bmw7();

    c->foo();       //gives output Bmw. Why output is not Car ??
    return 0;
}
foo1 не foo. Вы можете найти override полезным
user4581301 10.04.2019 06:20

Вы также можете проконсультироваться с этот список. Ничто не сравнится с хорошей проверенной книгой, которая поможет разобраться в таком сложном языке, как C++.

StoryTeller - Unslander Monica 10.04.2019 06:27

@ user4581301 Почему вы не считаете это ответом?

Yunnosch 10.04.2019 08:22

@Yunnosch Слишком похоже на опечатку. Если бы это было не так, для будущих программистов не было бы большой ценности в «Идентификаторы должны совпадать». Если вы не знаете, что по таймеру вы достигли переполнения стека, ваш справочный материал в лучшем случае сомнительный.

user4581301 10.04.2019 17:06

@ user4581301 В приведенном выше фрагменте кода, указанном в вопросе, нет опечатки. Мне задали этот вопрос в интервью Arcesium, и я не смог ответить. Мне отказали, и первое, что я сделал после этого, — разместил этот вопрос здесь. Прошло 2 года, и в настоящее время я работаю в материнской компании Arcesium D.E. Шоу, как разработчик C++ (SDE-II). Принятый ответ и все комментарии теперь имеют для меня смысл.

shubhamcr7 21.05.2021 17:43

Согласен, я не думаю, что прочитал вопрос достаточно внимательно, чтобы понять, что вы на самом деле спрашивали.

user4581301 21.05.2021 18:34
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
86
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Здесь — довольно хорошее объяснение виртуальных функций и виртуальных таблиц.

Every class that uses virtual functions (or is derived from a class that uses virtual functions) is given its own virtual table

Each entry in this table is simply a function pointer that points to the most-derived function accessible by that class.

Это в значительной степени отвечает на ваши вопросы. В первом примере самая производная функция, доступная c, — это функция Carfoo. А во втором это Bmwfoo. Здесь хоть вы и не написали virtual перед foo(что не очень хороший стиль кодирования) в Bmw, его виртуальность унаследована от Car.

Обновлено: Как было правильно сказано в комментарии, vtables не являются частью стандарта. См. эта ссылка для более формального объяснения.

For every virtual function, there is the final overrider, which is executed when a virtual function call is made. A virtual member function vf of a base class Base is the final overrider unless the derived class declares or inherits (through multiple inheritance) another function that overrides vf.

Примечание: C++ не требует использования VTables. VTables, безусловно, являются наиболее распространенной реализацией, потому что они выполняют работу прямым и относительно простым способом реализации, так что это то, что вы, скорее всего, увидите. Тем временем в секретных лабораториях по всему миру ведущие ученые работают над альтернативами, всегда ища лучшее решение.

user4581301 10.04.2019 18:41

Спасибо, да, только что предоставил этот ответ, поскольку вопрос был конкретно о vtable. Отредактировано.

Nellie Danielyan 10.04.2019 21:20

Другие вопросы по теме