Будет выведено 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. Срезки здесь нет: объект передаётся не по значению, а доступен через указатель.