Определите вывод программы с наследованием классов

Будет выведено B::foo с переводом строки. foo не является виртуальной, поэтому вызов выбирается по статическому типу pB — указателю на B.

Короткий ответ

Что ответить на собеседовании

Будет выведено B::foo с переводом строки. foo не является виртуальной, поэтому вызов выбирается по статическому типу pB — указателю на B.

Подробный разбор

Ответ с пояснениями

Условие

Нужно понять, какой текст будет выведен в консоль после выполнения следующего кода.

# include <iostream>

class A {
public:
    void foo() { std::cout << "A::foo\n"; }
};

class B : public A {
public:
    void foo() { std::cout << "B::foo\n"; }
};

class C : public B {
public:
    void foo() { std::cout << "C::foo\n"; }
};

int main() {
    C obj;
    B *pB = &obj;

    pB->foo();
}

Ответ

Будет выведено B::foo с переводом строки. foo не является виртуальной, поэтому вызов выбирается по статическому типу pB — указателю на B.

Объект действительно имеет тип C, но для невиртуального метода это не запускает динамическую диспетчеризацию. Одноимённые методы в B и C скрывают унаследованные имена.

Если объявить A::foo виртуальной, а методы B и C пометить override, тот же вызов через B* выполнит C::foo. Срезки здесь нет: объект передаётся не по значению, а доступен через указатель.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее