Почему не происходит переопределение?

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

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


int main()
{

    A* a = new A;

    ((B*)a)->foo();
    return 0;
}

Почему выводится именно Im From A class? Можно как-то кастить напрямую?


Ответы (1 шт):

Автор решения: Harry

Потому что функция виртуальная, так что работает динамическая диспетчеризация, так что что именно вызывать, выясняется во время выполнения. И поскольку a указывает именно на тип A, вызывается функция для него.

Если убрать виртуальность — получится статическая диспетчеризация, и компилятор вызовет B::foo(), исходя из типа, указанного во время компиляции. Только вот такой кастинг — приведение предка к потомку — на грани, если не за гранью фола. Для простых функций сработает, но сами подумайте, что будет, если вы попытаетесь обратиться к чему-то, чего в A нет, а в B есть? Так что в эти игры лучше не играть...

А если вы хотите получить вызов B::foo() через указатель на A, то это делается так:

A* a = new B;
a->foo();
→ Ссылка